Merge remote-tracking branch 'aosp/master'

This commit is contained in:
Martin Storsjo 2020-11-17 12:38:51 +02:00
commit c7a3808a2f
106 changed files with 2526 additions and 2149 deletions

View File

@ -1,6 +1,7 @@
cc_library_static {
name: "libFraunhoferAAC",
vendor_available: true,
host_supported: true,
srcs: [
"libAACdec/src/*.cpp",
"libAACenc/src/*.cpp",
@ -23,12 +24,13 @@ cc_library_static {
"-Wuninitialized",
"-Wno-self-assign",
"-Wno-implicit-fallthrough",
"-DSUPPRESS_BUILD_DATE_INFO",
],
sanitize: {
misc_undefined:[
"unsigned-integer-overflow",
"signed-integer-overflow",
"bounds",
misc_undefined: [
"unsigned-integer-overflow",
"signed-integer-overflow",
"bounds",
],
// Enable CFI if this becomes a shared library.
// cfi: true,
@ -51,4 +53,17 @@ cc_library_static {
"libSACdec/include",
"libSACenc/include",
],
target: {
darwin: {
enabled: false,
},
},
apex_available: [
"//apex_available:platform",
"com.android.bluetooth.updatable",
"com.android.media.swcodec",
],
min_sdk_version: "29",
}

3
METADATA Normal file
View File

@ -0,0 +1,3 @@
third_party {
license_type: BY_EXCEPTION_ONLY
}

2
PREUPLOAD.cfg Normal file
View 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.

46
fuzzer/Android.bp Normal file
View File

@ -0,0 +1,46 @@
/******************************************************************************
*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
cc_fuzz {
name: "aac_dec_fuzzer",
host_supported:true,
static_libs: [
"libFraunhoferAAC",
"liblog",
],
srcs: [
"aac_dec_fuzzer.cpp",
],
target: {
darwin: {
enabled: false,
},
},
fuzz_config: {
cc: [
"android-media-fuzzing-reports@google.com",
],
componentid: 155276,
},
}

59
fuzzer/README.md Normal file
View File

@ -0,0 +1,59 @@
# Fuzzer for libFraunhoferAAC decoder
## Plugin Design Considerations
The fuzzer plugin for aac decoder is designed based on the understanding of the
codec and tries to achieve the following:
##### Maximize code coverage
This fuzzer makes use of the following config parameters:
1. Transport type (parameter name: `TRANSPORT_TYPE`)
| Parameter| Valid Values| Configured Value|
|------------- |-------------| ----- |
| `TRANSPORT_TYPE` | 0.`TT_UNKNOWN ` 1.`TT_MP4_RAW ` 2.`TT_MP4_ADIF ` 3.`TT_MP4_ADTS ` 4.`TT_MP4_LATM_MCP1 ` 5.`TT_MP4_LATM_MCP0 ` 6.`TT_MP4_LOAS ` 7.`TT_DRM ` | `TT_MP4_ADIF ` |
Note: Value of `TRANSPORT_TYPE` could be set to any of these values.
It is set to `TT_MP4_ADIF` in the fuzzer plugin.
##### Maximize utilization of input data
The plugin feeds the entire input data to the codec using a loop.
* If the decode operation was successful, the input is advanced by an
offset calculated using valid bytes.
* If the decode operation was un-successful, the input is advanced by 1 byte
till it reaches a valid frame or end of stream.
This ensures that the plugin tolerates any kind of input (empty, huge,
malformed, etc) and doesnt `exit()` on any input and thereby increasing the
chance of identifying vulnerabilities.
## Build
This describes steps to build aac_dec_fuzzer binary.
## Android
### Steps to build
Build the fuzzer
```
$ mm -j$(nproc) aac_dec_fuzzer
```
### Steps to run
Create a directory CORPUS_DIR and copy some aac files to that folder.
Push this directory to device.
To run on device
```
$ adb sync data
$ adb shell /data/fuzz/arm64/aac_dec_fuzzer/aac_dec_fuzzer CORPUS_DIR
```
To run on host
```
$ $ANDROID_HOST_OUT/fuzz/x86_64/aac_dec_fuzzer/aac_dec_fuzzer CORPUS_DIR
```
## References:
* http://llvm.org/docs/LibFuzzer.html
* https://github.com/google/oss-fuzz

140
fuzzer/aac_dec_fuzzer.cpp Normal file
View File

@ -0,0 +1,140 @@
/******************************************************************************
*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <stdint.h>
#include <string.h>
#include <algorithm>
#include "aacdecoder_lib.h"
constexpr uint8_t kNumberOfLayers = 1;
constexpr uint8_t kMaxChannelCount = 8;
constexpr uint32_t kMaxConfigurationSize = 1024;
constexpr uint32_t kMaxOutBufferSize = 2048 * kMaxChannelCount;
// Value indicating the start of AAC Header Segment
constexpr const char *kAacSegStartSeq = "AAC_STRT";
constexpr uint8_t kAacSegStartSeqLen = sizeof(kAacSegStartSeq);
// Value indicating the end of AAC Header Segment
constexpr const char *kAacSegEndSeq = "AAC_ENDS";
constexpr uint8_t kAacSegEndSeqLen = sizeof(kAacSegEndSeq);
// Number of bytes used to signal the length of the header
constexpr uint8_t kHeaderLengthBytes = 2;
// Minimum size of an AAC header is 2
// Minimum data required is
// strlen(AAC_STRT) + strlen(AAC_ENDS) + kHeaderLengthBytes + 2;
constexpr UINT kMinDataSize = kAacSegStartSeqLen + kAacSegEndSeqLen + kHeaderLengthBytes + 2;
UINT getHeaderSize(UCHAR *data, UINT size) {
if (size < kMinDataSize) {
return 0;
}
int32_t result = memcmp(data, kAacSegStartSeq, kAacSegStartSeqLen);
if (result) {
return 0;
}
data += kAacSegStartSeqLen;
size -= kAacSegStartSeqLen;
uint32_t headerLengthInBytes = (data[0] << 8 | data[1]) & 0xFFFF;
data += kHeaderLengthBytes;
size -= kHeaderLengthBytes;
if (headerLengthInBytes + kAacSegEndSeqLen > size) {
return 0;
}
data += headerLengthInBytes;
size -= headerLengthInBytes;
result = memcmp(data, kAacSegEndSeq, kAacSegEndSeqLen);
if (result) {
return 0;
}
return std::min(headerLengthInBytes, kMaxConfigurationSize);
}
class Codec {
public:
Codec() = default;
~Codec() { deInitDecoder(); }
bool initDecoder();
void decodeFrames(UCHAR *data, UINT size);
void deInitDecoder();
private:
HANDLE_AACDECODER mAacDecoderHandle = nullptr;
AAC_DECODER_ERROR mErrorCode = AAC_DEC_OK;
};
bool Codec::initDecoder() {
mAacDecoderHandle = aacDecoder_Open(TT_MP4_ADIF, kNumberOfLayers);
if (!mAacDecoderHandle) {
return false;
}
return true;
}
void Codec::deInitDecoder() {
aacDecoder_Close(mAacDecoderHandle);
mAacDecoderHandle = nullptr;
}
void Codec::decodeFrames(UCHAR *data, UINT size) {
UINT headerSize = getHeaderSize(data, size);
if (headerSize != 0) {
data += kAacSegStartSeqLen + kHeaderLengthBytes;
size -= kAacSegStartSeqLen + kHeaderLengthBytes;
aacDecoder_ConfigRaw(mAacDecoderHandle, &data, &headerSize);
data += headerSize + kAacSegEndSeqLen;
size -= headerSize + kAacSegEndSeqLen;
}
while (size > 0) {
UINT inputSize = size;
UINT valid = size;
mErrorCode = aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid);
if (mErrorCode != AAC_DEC_OK) {
++data;
--size;
} else {
INT_PCM outputBuf[kMaxOutBufferSize];
do {
mErrorCode =
aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, sizeof(outputBuf), 0);
} while (mErrorCode == AAC_DEC_OK);
UINT offset = inputSize - valid;
data += offset;
size = valid;
}
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
Codec *codec = new Codec();
if (!codec) {
return 0;
}
if (codec->initDecoder()) {
codec->decodeFrames((UCHAR *)(data), static_cast<UINT>(size));
}
delete codec;
return 0;
}

View File

@ -164,9 +164,6 @@ The contents of each file is described in detail in this document. All header
files are provided for usage in specific C/C++ programs. The main AAC decoder
library API functions are located in aacdecoder_lib.h header file.
In binary releases the decoder core resides in statically linkable libraries,
for example libAACdec.a.
\section Calling_Sequence Calling Sequence
@ -174,19 +171,7 @@ The following sequence is necessary for proper decoding of ISO/MPEG-2/4 AAC,
HE-AAC v2, or MPEG-D USAC bitstreams. In the following description, input stream
read and output write function details are left out, since they may be
implemented in a variety of configurations depending on the user's specific
requirements. The example implementation uses file-based input/output, and in
such case one may call mpegFileRead_Open() to open an input file and to allocate
memory for the required structures, and the corresponding mpegFileRead_Close()
to close opened files and to de-allocate associated structures.
mpegFileRead_Open() will attempt to detect the bitstream format and in case of
MPEG-4 file format or Raw Packets file format (a proprietary Fraunhofer IIS file
format suitable only for testing) it will read the Audio Specific Config data
(ASC). An unsuccessful attempt to recognize the bitstream format requires the
user to provide this information manually. For any other bitstream formats that
are usually applicable in streaming applications, the decoder itself will try to
synchronize and parse the given bitstream fragment using the FDK transport
library. Hence, for streaming applications (without file access) this step is
not necessary.
requirements.
-# Call aacDecoder_Open() to open and retrieve a handle to a new AAC decoder
@ -205,19 +190,17 @@ do {
working memory (a client-supplied input buffer "inBuffer" in framework). This
buffer will be used to load AAC bitstream data to the decoder. Only when all
data in this buffer has been processed will the decoder signal an empty buffer.
For file-based input, you may invoke mpegFileRead_Read() to acquire new
bitstream data.
-# Call aacDecoder_Fill() to fill the decoder's internal bitstream input buffer
with the client-supplied bitstream input buffer. Note, if the data loaded in to
the internal buffer is not sufficient to decode a frame,
aacDecoder_DecodeFrame() will return ::AAC_DEC_NOT_ENOUGH_BITS until a
sufficient amount of data is loaded in to the internal buffer. For streaming
formats (ADTS, LOAS), it is acceptable to load more than one frame to the
decoder. However, for RAW file format (Fraunhofer IIS proprietary format), only
one frame may be loaded to the decoder per aacDecoder_DecodeFrame() call. For
least amount of communication delay, fill and decode should be performed on a
frame by frame basis. \code ErrorStatus = aacDecoder_Fill(aacDecoderInfo,
inBuffer, bytesRead, bytesValid); \endcode
decoder. However, for packed based formats, only one frame may be loaded to the
decoder per aacDecoder_DecodeFrame() call. For least amount of communication
delay, fill and decode should be performed on a frame by frame basis. \code
ErrorStatus = aacDecoder_Fill(aacDecoderInfo, inBuffer, bytesRead,
bytesValid); \endcode
-# Call aacDecoder_DecodeFrame(). This function decodes one frame and writes
decoded PCM audio data to a client-supplied buffer. It is the client's
responsibility to allocate a buffer which is large enough to hold the decoded
@ -225,12 +208,9 @@ output data. \code ErrorStatus = aacDecoder_DecodeFrame(aacDecoderInfo,
TimeData, OUT_BUF_SIZE, flags); \endcode If the bitstream configuration (number
of channels, sample rate, frame size) is not known a priori, you may call
aacDecoder_GetStreamInfo() to retrieve a structure that contains this
information. You may use this data to initialize an audio output device. In the
example program, if the number of channels or the sample rate has changed since
program start or the previously decoded frame, the audio output device is then
re-initialized. If WAVE file output is chosen, a new WAVE file for each new
stream configuration is be created. \code p_si =
aacDecoder_GetStreamInfo(aacDecoderInfo); \endcode
information. You may use this data to initialize an audio output device. \code
p_si = aacDecoder_GetStreamInfo(aacDecoderInfo);
\endcode
-# Repeat steps 5 to 7 until no data is available to decode any more, or in case
of error. \code } while (bytesRead[0] > 0 || doFlush || doBsFlush ||
forceContinue); \endcode
@ -239,7 +219,7 @@ structures. \code aacDecoder_Close(aacDecoderInfo); \endcode
\image latex decode.png "Decode calling sequence" width=11cm
\image latex change_source.png "Change data source sequence" width 5cm
\image latex change_source.png "Change data source sequence" width=5cm
\image latex conceal.png "Error concealment sequence" width=14cm
@ -296,16 +276,14 @@ input buffer, and one to hold the decoded output PCM sample data. In resource
limited applications, the output buffer may be reused as an external input
buffer prior to the subsequence aacDecoder_Fill() function call.
The external input buffer is set in the example program and its size is defined
by ::IN_BUF_SIZE. You may freely choose different buffer sizes. To feed the data
to the decoder-internal input buffer, use the function aacDecoder_Fill(). This
function returns important information regarding the number of bytes in the
external input buffer that have not yet been copied into the internal input
buffer (variable bytesValid). Once the external buffer has been fully copied, it
can be completely re-filled again. In case you wish to refill the buffer while
there are unprocessed bytes (bytesValid is unequal 0), you should preserve the
unconsumed data. However, we recommend to refill the buffer only when bytesValid
returns 0.
To feed the data to the decoder-internal input buffer, use the
function aacDecoder_Fill(). This function returns important information
regarding the number of bytes in the external input buffer that have not yet
been copied into the internal input buffer (variable bytesValid). Once the
external buffer has been fully copied, it can be completely re-filled again. In
case you wish to refill the buffer while there are unprocessed bytes (bytesValid
is unequal 0), you should preserve the unconsumed data. However, we recommend to
refill the buffer only when bytesValid returns 0.
The bytesValid parameter is an input and output parameter to the FDK decoder. As
an input, it signals how many valid bytes are available in the external buffer.
@ -340,10 +318,7 @@ explanation, please refer to ISO/IEC 13818-7:2005(E), chapter 8.5.3.2.
In case a Program Config is included in the audio configuration, the channel
mapping described within it will be adopted.
In case of MPEG-D Surround the channel mapping will follow the same criteria
described in ISO/IEC 13818-7:2005(E), but adding corresponding top channels (if
available) to the channel types in order to avoid ambiguity. The examples below
explain these aspects in detail.
The examples below explain these aspects in detail.
\section OutputFormatChange Changing the audio output format
@ -694,9 +669,7 @@ typedef enum {
2. If the parameter value is greater than that of
::AAC_PCM_MAX_OUTPUT_CHANNELS both will be set to the same
value. \n
3. This parameter does not affect MPEG Surround processing.
\n
4. This parameter will be ignored if the number of encoded
3. This parameter will be ignored if the number of encoded
audio channels is greater than 8. */
AAC_PCM_MAX_OUTPUT_CHANNELS =
0x0012, /*!< Maximum number of PCM output channels. If lower than the
@ -723,11 +696,7 @@ typedef enum {
2. If the parameter value is greater than zero but smaller
than ::AAC_PCM_MIN_OUTPUT_CHANNELS both will be set to same
value. \n
3. The operating mode of the MPEG Surround module will be
set accordingly. \n
4. Setting this parameter with any value will disable the
binaural processing of the MPEG Surround module
5. This parameter will be ignored if the number of encoded
3. This parameter will be ignored if the number of encoded
audio channels is greater than 8. */
AAC_METADATA_PROFILE =
0x0020, /*!< See ::AAC_MD_PROFILE for all available values. */
@ -808,11 +777,11 @@ typedef enum {
sequences for fading in and out, if provided in the
bitstream.\n Enabled album mode makes use of dedicated album
loudness information, if provided in the bitstream.\n */
AAC_QMF_LOWPOWER = 0x0300, /*!< Quadrature Mirror Filter (QMF) Bank processing
mode. \n -1: Use internal default. Implies MPEG
Surround partially complex accordingly. \n 0:
Use complex QMF data mode. \n 1: Use real (low
power) QMF data mode. \n */
AAC_QMF_LOWPOWER =
0x0300, /*!< Quadrature Mirror Filter (QMF) Bank processing mode. \n
-1: Use internal default. \n
0: Use complex QMF data mode. \n
1: Use real (low power) QMF data mode. \n */
AAC_TPDEC_CLEAR_BUFFER =
0x0603 /*!< Clear internal bit stream buffer of transport layers. The
decoder will start decoding at new data passed after this event
@ -897,15 +866,25 @@ typedef struct {
1770. If no level has been found in the bitstream the
value is -1. */
SCHAR
drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154,
this field indicates whether light (MPEG-4 Dynamic Range
Control tool) or heavy compression (DVB heavy
compression) dynamic range control shall take priority
on the outputs. For details, see ETSI TS 101 154, table
C.33. Possible values are: \n -1: No corresponding
metadata found in the bitstream \n 0: DRC presentation
mode not indicated \n 1: DRC presentation mode 1 \n 2:
DRC presentation mode 2 \n 3: Reserved */
drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154,
this field indicates whether light (MPEG-4 Dynamic Range
Control tool) or heavy compression (DVB heavy
compression) dynamic range control shall take priority
on the outputs. For details, see ETSI TS 101 154, table
C.33. Possible values are: \n -1: No corresponding
metadata found in the bitstream \n 0: DRC presentation
mode not indicated \n 1: DRC presentation mode 1 \n 2:
DRC presentation mode 2 \n 3: Reserved */
INT outputLoudness; /*!< Audio output loudness in steps of -0.25 dB. Range: 0
(0 dBFS) to 231 (-57.75 dBFS).\n A value of -1
indicates that no loudness metadata is present.\n If
loudness normalization is active, the value corresponds
to the target loudness value set with
::AAC_DRC_REFERENCE_LEVEL.\n If loudness normalization
is not active, the output loudness value corresponds to
the loudness metadata given in the bitstream.\n
Loudness metadata can originate from MPEG-4 DRC or
MPEG-D DRC. */
} CStreamInfo;
@ -1033,21 +1012,24 @@ LINKSPEC_H AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self,
const UINT bufferSize[],
UINT *bytesValid);
#define AACDEC_CONCEAL \
1 /*!< Flag for aacDecoder_DecodeFrame(): Trigger the built-in error \
concealment module to generate a substitute signal for one lost frame. \
New input data will not be considered. */
#define AACDEC_FLUSH \
2 /*!< Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all \
delayed audio without having new input data. Thus new input data will \
not be considered.*/
#define AACDEC_INTR \
4 /*!< Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data \
discontinuity. Resync any internals as necessary. */
#define AACDEC_CLRHIST \
8 /*!< Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and \
history buffers. CAUTION: This can cause discontinuities in the output \
signal. */
/** Flag for aacDecoder_DecodeFrame(): Trigger the built-in error concealment
* module to generate a substitute signal for one lost frame. New input data
* will not be considered.
*/
#define AACDEC_CONCEAL 1
/** Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all delayed
* audio without having new input data. Thus new input data will not be
* considered.
*/
#define AACDEC_FLUSH 2
/** Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data
* discontinuity. Resync any internals as necessary.
*/
#define AACDEC_INTR 4
/** Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and history
* buffers. CAUTION: This can cause discontinuities in the output signal.
*/
#define AACDEC_CLRHIST 8
/**
* \brief Decode one audio frame

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -113,7 +113,7 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
if (delay > 0) {
data->delay_line =
(INT_PCM*)FDKcalloc(num_channels * delay, sizeof(INT_PCM));
(PCM_DEC*)FDKcalloc(num_channels * delay, sizeof(PCM_DEC));
if (data->delay_line == NULL) {
return -1;
}
@ -126,36 +126,36 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
return 0;
}
void FDK_Delay_Apply(FDK_SignalDelay* data, FIXP_PCM* time_buffer,
void FDK_Delay_Apply(FDK_SignalDelay* data, PCM_DEC* time_buffer,
const UINT frame_length, const UCHAR channel) {
FDK_ASSERT(data != NULL);
if (data->delay > 0) {
C_ALLOC_SCRATCH_START(tmp, FIXP_PCM, MAX_FRAME_LENGTH)
C_ALLOC_SCRATCH_START(tmp, PCM_DEC, MAX_FRAME_LENGTH)
FDK_ASSERT(frame_length <= MAX_FRAME_LENGTH);
FDK_ASSERT(channel < data->num_channels);
FDK_ASSERT(time_buffer != NULL);
if (frame_length >= data->delay) {
FDKmemcpy(tmp, &time_buffer[frame_length - data->delay],
data->delay * sizeof(FIXP_PCM));
data->delay * sizeof(PCM_DEC));
FDKmemmove(&time_buffer[data->delay], &time_buffer[0],
(frame_length - data->delay) * sizeof(FIXP_PCM));
(frame_length - data->delay) * sizeof(PCM_DEC));
FDKmemcpy(&time_buffer[0], &data->delay_line[channel * data->delay],
data->delay * sizeof(FIXP_PCM));
data->delay * sizeof(PCM_DEC));
FDKmemcpy(&data->delay_line[channel * data->delay], tmp,
data->delay * sizeof(FIXP_PCM));
data->delay * sizeof(PCM_DEC));
} else {
FDKmemcpy(tmp, &time_buffer[0], frame_length * sizeof(FIXP_PCM));
FDKmemcpy(tmp, &time_buffer[0], frame_length * sizeof(PCM_DEC));
FDKmemcpy(&time_buffer[0], &data->delay_line[channel * data->delay],
frame_length * sizeof(FIXP_PCM));
frame_length * sizeof(PCM_DEC));
FDKmemcpy(&data->delay_line[channel * data->delay],
&data->delay_line[channel * data->delay + frame_length],
(data->delay - frame_length) * sizeof(FIXP_PCM));
(data->delay - frame_length) * sizeof(PCM_DEC));
FDKmemcpy(&data->delay_line[channel * data->delay +
(data->delay - frame_length)],
tmp, frame_length * sizeof(FIXP_PCM));
tmp, frame_length * sizeof(PCM_DEC));
}
C_ALLOC_SCRATCH_END(tmp, FIXP_PCM, MAX_FRAME_LENGTH)
C_ALLOC_SCRATCH_END(tmp, PCM_DEC, MAX_FRAME_LENGTH)
}
return;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -109,7 +109,7 @@ amm-info@iis.fraunhofer.de
* Structure representing one delay element for multiple channels.
*/
typedef struct {
INT_PCM* delay_line; /*!< Pointer which stores allocated delay line. */
PCM_DEC* delay_line; /*!< Pointer which stores allocated delay line. */
USHORT delay; /*!< Delay required in samples (per channel). */
UCHAR num_channels; /*!< Number of channels to delay. */
} FDK_SignalDelay;
@ -137,7 +137,7 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
*
* \return void
*/
void FDK_Delay_Apply(FDK_SignalDelay* data, FIXP_PCM* time_buffer,
void FDK_Delay_Apply(FDK_SignalDelay* data, PCM_DEC* time_buffer,
const UINT frame_length, const UCHAR channel);
/**

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -105,12 +105,7 @@ amm-info@iis.fraunhofer.de
#define WORKBUFFER1_TAG 0
#define WORKBUFFER2_TAG 1
#define WORKBUFFER3_TAG 4
#define WORKBUFFER4_TAG 5
#define WORKBUFFER5_TAG 6
#define WORKBUFFER6_TAG 7
/*! The structure AAC_DECODER_INSTANCE is the top level structure holding all
@ -169,9 +164,6 @@ C_ALLOC_MEM2(TimeDataFlush, INT_PCM, TIME_DATA_FLUSH_SIZE, (8))
C_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL, ((8) * 1024), SECT_DATA_L2,
WORKBUFFER2_TAG)
C_ALLOC_MEM_OVERLAY(WorkBufferCore3, FIXP_DBL, WB_SECTION_SIZE, SECT_DATA_L2,
WORKBUFFER3_TAG)
C_AALLOC_MEM(WorkBufferCore4, FIXP_DBL, WB_SECTION_SIZE)
C_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR,
fMax((INT)(sizeof(FIXP_DBL) * WB_SECTION_SIZE),
(INT)sizeof(CAacDecoderCommonData)),

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -136,12 +136,7 @@ H_ALLOC_MEM(TimeDataFlush, INT_PCM)
H_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1)
H_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL)
H_ALLOC_MEM_OVERLAY(WorkBufferCore3, FIXP_DBL)
H_ALLOC_MEM(WorkBufferCore4, FIXP_DBL)
H_ALLOC_MEM_OVERLAY(WorkBufferCore5, PCM_DEC)
H_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR)
#endif /* #ifndef AAC_RAM_H */

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -108,6 +108,7 @@ amm-info@iis.fraunhofer.de
#include "aacdec_hcr_types.h"
#include "aacdec_hcrs.h"
#define PCM_AAC LONG
#define PCM_DEC FIXP_DBL
#define MAXVAL_PCM_DEC MAXVAL_DBL
#define MINVAL_PCM_DEC MINVAL_DBL

View File

@ -149,6 +149,20 @@ static INT convert_drcParam(FIXP_DBL param_dbl) {
return (INT)param_long;
}
/*!
\brief Reset DRC information
\self Handle of DRC info
\return none
*/
void aacDecoder_drcReset(HANDLE_AAC_DRC self) {
self->applyExtGain = 0;
self->additionalGainPrev = AACDEC_DRC_GAIN_INIT_VALUE;
self->additionalGainFilterState = AACDEC_DRC_GAIN_INIT_VALUE;
self->additionalGainFilterState1 = AACDEC_DRC_GAIN_INIT_VALUE;
}
/*!
\brief Initialize DRC information
@ -176,7 +190,6 @@ void aacDecoder_drcInit(HANDLE_AAC_DRC self) {
pParams->usrBoost = FL2FXCONST_DBL(0.0f);
pParams->targetRefLevel = 96;
pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES;
pParams->applyDigitalNorm = ON;
pParams->applyHeavyCompression = OFF;
pParams->usrApplyHeavyCompression = OFF;
@ -192,6 +205,8 @@ void aacDecoder_drcInit(HANDLE_AAC_DRC self) {
self->progRefLevelPresent = 0;
self->presMode = -1;
self->uniDrcPrecedence = 0;
aacDecoder_drcReset(self);
}
/*!
@ -258,11 +273,8 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self,
return AAC_DEC_INVALID_HANDLE;
}
if (value < 0) {
self->params.applyDigitalNorm = OFF;
self->params.targetRefLevel = -1;
} else {
/* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */
self->params.applyDigitalNorm = ON;
if (self->params.targetRefLevel != (SCHAR)value) {
self->params.targetRefLevel = (SCHAR)value;
self->progRefLevel = (SCHAR)value; /* Always set the program reference
@ -273,16 +285,6 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self,
self->update = 1;
}
break;
case APPLY_NORMALIZATION:
if ((value != OFF) && (value != ON)) {
return AAC_DEC_SET_PARAM_FAIL;
}
if (self == NULL) {
return AAC_DEC_INVALID_HANDLE;
}
/* Store new parameter value */
self->params.applyDigitalNorm = (UCHAR)value;
break;
case APPLY_HEAVY_COMPRESSION:
if ((value != OFF) && (value != ON)) {
return AAC_DEC_SET_PARAM_FAIL;
@ -910,11 +912,9 @@ void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec,
FDK_ASSERT(0);
}
}
if (self->params.applyDigitalNorm == OFF) {
/* Reset normalization gain since this module must not apply it */
norm_mantissa = FL2FXCONST_DBL(0.5f);
norm_exponent = 1;
}
/* Reset normalization gain since this module must not apply it */
norm_mantissa = FL2FXCONST_DBL(0.5f);
norm_exponent = 1;
/* calc scale factors */
for (band = 0; band < numBands; band++) {
@ -1353,3 +1353,152 @@ void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
}
}
}
/**
* \brief Apply DRC Level Normalization.
*
* This function prepares/applies the gain values for the DRC Level
* Normalization and returns the exponent of the time data. The following two
* cases are handled:
*
* - Limiter enabled:
* The input data must be interleaved.
* One gain per sample is written to the buffer pGainPerSample.
* If necessary the time data is rescaled.
*
* - Limiter disabled:
* The input data can be interleaved or deinterleaved.
* The gain values are applied to the time data.
* If necessary the time data is rescaled.
*
* \param hDrcInfo [i/o] handle to drc data structure.
* \param samplesIn [i/o] pointer to time data.
* \param pGain [i ] pointer to gain to be applied to
* the time data.
* \param pGainPerSample [o ] pointer to the gain per sample to
* be applied to the time data in the limiter.
* \param gain_scale [i ] exponent to be applied to the time
* data.
* \param gain_delay [i ] delay[samples] with which the gains
* in pGain shall be applied (gain_delay <= nSamples).
* \param nSamples [i ] number of samples per frame.
* \param channels [i ] number of channels.
* \param stride [i ] channel stride of time data.
* \param limiterEnabled [i ] 1 if limiter is enabled, otherwise
* 0.
*
* \return exponent of time data
*/
INT applyDrcLevelNormalization(HANDLE_AAC_DRC hDrcInfo, PCM_DEC *samplesIn,
FIXP_DBL *pGain, FIXP_DBL *pGainPerSample,
const INT gain_scale, const UINT gain_delay,
const UINT nSamples, const UINT channels,
const UINT stride, const UINT limiterEnabled) {
UINT i;
INT additionalGain_scaling;
FIXP_DBL additionalGain;
FDK_ASSERT(gain_delay <= nSamples);
FIXP_DBL additionalGainSmoothState = hDrcInfo->additionalGainFilterState;
FIXP_DBL additionalGainSmoothState1 = hDrcInfo->additionalGainFilterState1;
if (!gain_delay) {
additionalGain = pGain[0];
/* Apply the additional scaling gain_scale[0] that has no delay and no
* smoothing */
additionalGain_scaling =
fMin(gain_scale, CntLeadingZeros(additionalGain) - 1);
additionalGain = scaleValue(additionalGain, additionalGain_scaling);
/* if it's not possible to fully apply gain_scale to additionalGain, apply
* it to the input signal */
additionalGain_scaling -= gain_scale;
if (additionalGain_scaling) {
scaleValuesSaturate(samplesIn, channels * nSamples,
-additionalGain_scaling);
}
if (limiterEnabled) {
FDK_ASSERT(pGainPerSample != NULL);
for (i = 0; i < nSamples; i++) {
pGainPerSample[i] = additionalGain;
}
} else {
for (i = 0; i < channels * nSamples; i++) {
samplesIn[i] = FIXP_DBL2PCM_DEC(fMult(samplesIn[i], additionalGain));
}
}
} else {
UINT inc;
FIXP_DBL additionalGainUnfiltered;
inc = (stride == 1) ? channels : 1;
for (i = 0; i < nSamples; i++) {
if (i < gain_delay) {
additionalGainUnfiltered = hDrcInfo->additionalGainPrev;
} else {
additionalGainUnfiltered = pGain[0];
}
/* Smooth additionalGain */
/* [b,a] = butter(1, 0.01) */
static const FIXP_SGL b[] = {FL2FXCONST_SGL(0.015466 * 2.0),
FL2FXCONST_SGL(0.015466 * 2.0)};
static const FIXP_SGL a[] = {(FIXP_SGL)MAXVAL_SGL,
FL2FXCONST_SGL(-0.96907)};
additionalGain = -fMult(additionalGainSmoothState, a[1]) +
fMultDiv2(additionalGainUnfiltered, b[0]) +
fMultDiv2(additionalGainSmoothState1, b[1]);
additionalGainSmoothState1 = additionalGainUnfiltered;
additionalGainSmoothState = additionalGain;
/* Apply the additional scaling gain_scale[0] that has no delay and no
* smoothing */
additionalGain_scaling =
fMin(gain_scale, CntLeadingZeros(additionalGain) - 1);
additionalGain = scaleValue(additionalGain, additionalGain_scaling);
/* if it's not possible to fully apply gain_scale[0] to additionalGain,
* apply it to the input signal */
additionalGain_scaling -= gain_scale;
if (limiterEnabled) {
FDK_ASSERT(stride == 1);
FDK_ASSERT(pGainPerSample != NULL);
if (additionalGain_scaling) {
scaleValuesSaturate(samplesIn, channels, -additionalGain_scaling);
}
pGainPerSample[i] = additionalGain;
} else {
if (additionalGain_scaling) {
for (UINT k = 0; k < channels; k++) {
scaleValuesSaturate(&samplesIn[k * stride], 1,
-additionalGain_scaling);
}
}
for (UINT k = 0; k < channels; k++) {
samplesIn[k * stride] =
FIXP_DBL2PCM_DEC(fMult(samplesIn[k * stride], additionalGain));
}
}
samplesIn += inc;
}
}
hDrcInfo->additionalGainPrev = pGain[0];
hDrcInfo->additionalGainFilterState = additionalGainSmoothState;
hDrcInfo->additionalGainFilterState1 = additionalGainSmoothState1;
return (AACDEC_DRC_GAIN_SCALING);
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -109,6 +109,11 @@ amm-info@iis.fraunhofer.de
#include "channel.h"
#include "FDK_bitstream.h"
#define AACDEC_DRC_GAIN_SCALING (11) /* Scaling of DRC gains */
#define AACDEC_DRC_GAIN_INIT_VALUE \
(FL2FXCONST_DBL( \
1.0f / (1 << AACDEC_DRC_GAIN_SCALING))) /* Init value for DRC gains */
#define AACDEC_DRC_DFLT_EXPIRY_FRAMES \
(0) /* Default DRC data expiry time in AAC frames */
@ -125,7 +130,6 @@ typedef enum {
TARGET_REF_LEVEL,
DRC_BS_DELAY,
DRC_DATA_EXPIRY_FRAME,
APPLY_NORMALIZATION,
APPLY_HEAVY_COMPRESSION,
DEFAULT_PRESENTATION_MODE,
ENCODER_TARGET_LEVEL,
@ -136,6 +140,8 @@ typedef enum {
/**
* \brief DRC module interface functions
*/
void aacDecoder_drcReset(HANDLE_AAC_DRC self);
void aacDecoder_drcInit(HANDLE_AAC_DRC self);
void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChannel);
@ -189,4 +195,45 @@ int aacDecoder_drcEpilog(
void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
SCHAR *pProgRefLevel);
/**
* \brief Apply DRC Level Normalization.
*
* This function prepares/applies the gain values for the DRC Level
* Normalization and returns the exponent of the time data. The following two
* cases are handled:
*
* - Limiter enabled:
* The input data must be interleaved.
* One gain per sample is written to the buffer pGainPerSample.
* If necessary the time data is rescaled.
*
* - Limiter disabled:
* The input data can be interleaved or deinterleaved.
* The gain values are applied to the time data.
* If necessary the time data is rescaled.
*
* \param hDrcInfo [i/o] handle to drc data structure.
* \param samplesIn [i/o] pointer to time data.
* \param pGain [i ] pointer to gain to be applied to
* the time data.
* \param pGainPerSample [o ] pointer to the gain per sample to
* be applied to the time data in the limiter.
* \param gain_scale [i ] exponent to be applied to the time
* data.
* \param gain_delay [i ] delay[samples] with which the gains
* in pGain shall be applied (gain_delay <= nSamples).
* \param nSamples [i ] number of samples per frame.
* \param channels [i ] number of channels.
* \param stride [i ] channel stride of time data.
* \param limiterEnabled [i ] 1 if limiter is enabled, otherwise
* 0.
*
* \return exponent of time data
*/
INT applyDrcLevelNormalization(HANDLE_AAC_DRC hDrcInfo, PCM_DEC *samplesIn,
FIXP_DBL *pGain, FIXP_DBL *pGainPerSample,
const INT gain_scale, const UINT gain_delay,
const UINT nSamples, const UINT channels,
const UINT stride, const UINT limiterEnabled);
#endif /* AACDEC_DRC_H */

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -168,7 +168,6 @@ typedef struct {
UINT expiryFrame;
UCHAR bsDelayEnable;
UCHAR applyDigitalNorm;
AACDEC_DRC_PARAMETER_HANDLING defaultPresentationMode;
UCHAR encoderTargetLevel;
@ -213,6 +212,13 @@ typedef struct {
uniDrcPrecedence; /* Flag for signalling that uniDrc is active and takes
precedence over legacy DRC */
UCHAR applyExtGain; /* Flag is 1 if extGain has to be applied, otherwise 0. */
FIXP_DBL additionalGainPrev; /* Gain of previous frame to be applied to the
time data */
FIXP_DBL additionalGainFilterState; /* Filter state for the gain smoothing */
FIXP_DBL additionalGainFilterState1; /* Filter state for the gain smoothing */
} CDrcInfo;
typedef CDrcInfo *HANDLE_AAC_DRC;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -137,7 +137,7 @@ static void DeriveNumberOfExtendedSortedSectionsInSets(
static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
INT quantSpecCoef, INT *pLeftStartOfSegment,
SCHAR *pRemainingBitsInSegment,
int *pNumDecodedBits);
int *pNumDecodedBits, UINT *errorWord);
static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
UINT codebookDim, const SCHAR *pQuantVal,
@ -1179,8 +1179,8 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
bs, pHcr->decInOut.bitstreamAnchor,
pQuantizedSpectralCoefficients
[quantizedSpectralCoefficientsIdx],
pLeftStartOfSegment, pRemainingBitsInSegment,
&numDecodedBits);
pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits,
&pHcr->decInOut.errorLog);
}
quantizedSpectralCoefficientsIdx++;
if (quantizedSpectralCoefficientsIdx >= 1024) {
@ -1195,8 +1195,8 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
bs, pHcr->decInOut.bitstreamAnchor,
pQuantizedSpectralCoefficients
[quantizedSpectralCoefficientsIdx],
pLeftStartOfSegment, pRemainingBitsInSegment,
&numDecodedBits);
pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits,
&pHcr->decInOut.errorLog);
}
quantizedSpectralCoefficientsIdx++;
if (quantizedSpectralCoefficientsIdx >= 1024) {
@ -1386,7 +1386,7 @@ value == 16, a escapeSequence is decoded in two steps:
static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
INT quantSpecCoef, INT *pLeftStartOfSegment,
SCHAR *pRemainingBitsInSegment,
int *pNumDecodedBits) {
int *pNumDecodedBits, UINT *errorWord) {
UINT i;
INT sign;
UINT escapeOnesCounter = 0;
@ -1400,6 +1400,9 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
FROM_LEFT_TO_RIGHT);
*pRemainingBitsInSegment -= 1;
*pNumDecodedBits += 1;
if (*pRemainingBitsInSegment < 0) {
return Q_VALUE_INVALID;
}
if (carryBit != 0) {
escapeOnesCounter += 1;
@ -1416,6 +1419,9 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
FROM_LEFT_TO_RIGHT);
*pRemainingBitsInSegment -= 1;
*pNumDecodedBits += 1;
if (*pRemainingBitsInSegment < 0) {
return Q_VALUE_INVALID;
}
escape_word <<= 1;
escape_word = escape_word | carryBit;
@ -1423,11 +1429,12 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
sign = (quantSpecCoef >= 0) ? 1 : -1;
if (escapeOnesCounter > 30)
escapeOnesCounter = 30;
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;
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -1324,6 +1324,10 @@ UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM bs, void *ptr) {
/* count ones and store sum in escapePrefixUp */
if (carryBit == 1) {
escapePrefixUp += 1; /* update conter for ones */
if (escapePrefixUp > 8) {
pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX;
return BODY_SIGN_ESC__ESC_PREFIX;
}
/* store updated counter in sideinfo of current codeword */
pEscapeSequenceInfo[codewordOffset] &=

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -1225,6 +1225,8 @@ static void CStreamInfoInit(CStreamInfo *pStreamInfo) {
pStreamInfo->drcProgRefLev =
-1; /* set program reference level to not indicated */
pStreamInfo->drcPresMode = -1; /* default: presentation mode not indicated */
pStreamInfo->outputLoudness = -1; /* default: no loudness metadata present */
}
/*!
@ -1279,6 +1281,7 @@ LINKSPEC_CPP HANDLE_AACDECODER CAacDecoder_Open(
/* Set default frame delay */
aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY,
CConcealment_GetDelay(&self->concealCommonData));
self->workBufferCore1 = (FIXP_DBL *)GetWorkBufferCore1();
self->workBufferCore2 = GetWorkBufferCore2();
if (self->workBufferCore2 == NULL) goto bail;
@ -1303,7 +1306,8 @@ static void CAacDecoder_DeInit(HANDLE_AACDECODER self,
const int subStreamIndex) {
int ch;
int aacChannelOffset = 0, aacChannels = (8);
int numElements = (((8)) + (8)), elementOffset = 0;
int numElements = (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1),
elementOffset = 0;
if (self == NULL) return;
@ -1453,6 +1457,10 @@ LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self) {
FreeDrcInfo(&self->hDrcInfo);
}
if (self->workBufferCore1 != NULL) {
FreeWorkBufferCore1((CWorkBufferCore1 **)&self->workBufferCore1);
}
/* Free WorkBufferCore2 */
if (self->workBufferCore2 != NULL) {
FreeWorkBufferCore2(&self->workBufferCore2);
@ -1490,6 +1498,8 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
UCHAR downscaleFactor = self->downscaleFactor;
UCHAR downscaleFactorInBS = self->downscaleFactorInBS;
self->aacOutDataHeadroom = (3);
// set profile and check for supported aot
// leave profile on default (=-1) for all other supported MPEG-4 aot's except
// aot=2 (=AAC-LC)
@ -1847,6 +1857,12 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
self->streamInfo.extSamplingRate / self->downscaleFactor;
}
}
if ((asc->m_aot == AOT_AAC_LC) && (asc->m_sbrPresentFlag == 1) &&
(asc->m_extensionSamplingFrequency > (2 * asc->m_samplingFrequency))) {
return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* Core decoder supports at most a
1:2 upsampling for HE-AAC and
HE-AACv2 */
}
/* --------- vcb11 ------------ */
self->flags[streamIndex] |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0;
@ -1928,6 +1944,9 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
self->samplingRateInfo[0].samplingRate / self->downscaleFactor;
self->streamInfo.aacSamplesPerFrame =
asc->m_samplesPerFrame / self->downscaleFactor;
if (self->streamInfo.aacSampleRate <= 0) {
return AAC_DEC_UNSUPPORTED_SAMPLINGRATE;
}
}
}
@ -2362,6 +2381,13 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
goto bail;
}
if (*configChanged) {
if (asc->m_aot == AOT_USAC) {
self->hDrcInfo->enable = 0;
self->hDrcInfo->progRefLevelPresent = 0;
}
}
if (asc->m_aot == AOT_USAC) {
pcmLimiter_SetAttack(self->hLimiter, (5));
pcmLimiter_SetThreshold(self->hLimiter, FL2FXCONST_DBL(0.89125094f));
@ -2375,7 +2401,7 @@ bail:
}
LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
HANDLE_AACDECODER self, const UINT flags, FIXP_PCM *pTimeData,
HANDLE_AACDECODER self, const UINT flags, PCM_DEC *pTimeData,
const INT timeDataSize, const int timeDataChannelOffset) {
AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
@ -3151,11 +3177,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
FDKmemcpy(drcChMap, self->chMapping, (8) * sizeof(UCHAR));
}
/* Turn on/off DRC modules level normalization in digital domain depending
* on the limiter status. */
aacDecoder_drcSetParam(self->hDrcInfo, APPLY_NORMALIZATION,
(self->limiterEnableCurr) ? 0 : 1);
/* deactivate legacy DRC in case uniDrc is active, i.e. uniDrc payload is
* present and one of DRC or Loudness Normalization is switched on */
aacDecoder_drcSetParam(
@ -3168,9 +3189,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
pce->ElementInstanceTag, drcChMap, aacChannels);
if (mapped > 0) {
/* If at least one DRC thread has been mapped to a channel threre was DRC
* data in the bitstream. */
self->flags[streamIndex] |= AC_DRC_PRESENT;
if (!(self->flags[streamIndex] & (AC_USAC | AC_RSV603DA))) {
/* If at least one DRC thread has been mapped to a channel there was DRC
* data in the bitstream. */
self->flags[streamIndex] |= AC_DRC_PRESENT;
} else {
self->hDrcInfo->enable = 0;
self->hDrcInfo->progRefLevelPresent = 0;
ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
}
}
/* Create a reverse mapping table */
@ -3300,9 +3327,11 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
&pAacDecoderStaticChannelInfo->drcData);
}
}
/* The DRC module demands to be called with the gain field holding the
* gain scale. */
self->extGain[0] = (FIXP_DBL)TDL_GAIN_SCALING;
self->extGain[0] = (FIXP_DBL)AACDEC_DRC_GAIN_SCALING;
/* DRC processing */
aacDecoder_drcApply(
self->hDrcInfo, self->hSbrDecoder, pAacDecoderChannelInfo,
@ -3318,7 +3347,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
if (self->flushStatus && (self->flushCnt > 0) &&
!(flags & AACDEC_CONCEAL)) {
FDKmemclear(pTimeData + offset,
sizeof(FIXP_PCM) * self->streamInfo.aacSamplesPerFrame);
sizeof(PCM_DEC) * self->streamInfo.aacSamplesPerFrame);
} else
switch (pAacDecoderChannelInfo->renderMode) {
case AACDEC_RENDER_IMDCT:
@ -3330,7 +3359,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
!frameOk_butConceal),
pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1
->mdctOutTemp,
self->elFlags[el], elCh);
self->aacOutDataHeadroom, self->elFlags[el], elCh);
self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
break;
@ -3351,7 +3380,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
&self->samplingRateInfo[streamIndex],
(self->frameOK && !(flags & AACDEC_CONCEAL) &&
!frameOk_butConceal),
flags, self->flags[streamIndex]);
self->aacOutDataHeadroom, flags, self->flags[streamIndex]);
self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
break;
@ -3363,7 +3392,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
if (!CConceal_TDFading_Applied[c]) {
CConceal_TDFading_Applied[c] = CConcealment_TDFading(
self->streamInfo.aacSamplesPerFrame,
&self->pAacDecoderStaticChannelInfo[c], pTimeData + offset, 0);
&self->pAacDecoderStaticChannelInfo[c], self->aacOutDataHeadroom,
pTimeData + offset, 0);
if (c + 1 < (8) && c < aacChannels - 1) {
/* update next TDNoise Seed to avoid muting in case of Parametric
* Stereo */
@ -3385,22 +3415,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
if ((aacChannels == 2) && bsPseudoLr) {
int i, offset2;
const FIXP_SGL invSqrt2 = FL2FXCONST_SGL(0.707106781186547f);
FIXP_PCM *pTD = pTimeData;
PCM_DEC *pTD = pTimeData;
offset2 = timeDataChannelOffset;
for (i = 0; i < self->streamInfo.aacSamplesPerFrame; i++) {
FIXP_DBL L = FX_PCM2FX_DBL(pTD[0]);
FIXP_DBL R = FX_PCM2FX_DBL(pTD[offset2]);
FIXP_DBL L = PCM_DEC2FIXP_DBL(pTD[0]);
FIXP_DBL R = PCM_DEC2FIXP_DBL(pTD[offset2]);
L = fMult(L, invSqrt2);
R = fMult(R, invSqrt2);
#if (SAMPLE_BITS == 16)
pTD[0] = FX_DBL2FX_PCM(fAddSaturate(L + R, (FIXP_DBL)0x8000));
pTD[offset2] = FX_DBL2FX_PCM(fAddSaturate(L - R, (FIXP_DBL)0x8000));
#else
pTD[0] = FX_DBL2FX_PCM(L + R);
pTD[offset2] = FX_DBL2FX_PCM(L - R);
#endif
pTD[0] = L + R;
pTD[offset2] = L - R;
pTD++;
}
}
@ -3411,9 +3436,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
pce->ElementInstanceTag, drcChMap, aacChannels);
if (mapped > 0) {
/* If at least one DRC thread has been mapped to a channel threre was DRC
* data in the bitstream. */
self->flags[streamIndex] |= AC_DRC_PRESENT;
if (!(self->flags[streamIndex] & (AC_USAC | AC_RSV603DA))) {
/* If at least one DRC thread has been mapped to a channel there was DRC
* data in the bitstream. */
self->flags[streamIndex] |= AC_DRC_PRESENT;
} else {
self->hDrcInfo->enable = 0;
self->hDrcInfo->progRefLevelPresent = 0;
ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
}
}
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -191,6 +191,9 @@ struct AAC_DECODER_INSTANCE {
INT outputInterleaved; /*!< PCM output format (interleaved/none interleaved).
*/
INT aacOutDataHeadroom; /*!< Headroom of the output time signal to prevent
clipping */
HANDLE_TRANSPORTDEC hInput; /*!< Transport layer handle. */
SamplingRateInfo
@ -235,6 +238,7 @@ struct AAC_DECODER_INSTANCE {
CAacDecoderStaticChannelInfo
*pAacDecoderStaticChannelInfo[(8)]; /*!< Persistent channel memory */
FIXP_DBL *workBufferCore1;
FIXP_DBL *workBufferCore2;
PCM_DEC *pTimeData2;
INT timeData2Size;
@ -311,11 +315,10 @@ This structure is allocated once for each CPE. */
UCHAR limiterEnableUser; /*!< The limiter configuration requested by the
library user */
UCHAR limiterEnableCurr; /*!< The current limiter configuration. */
FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */
UINT extGainDelay; /*!< Delay that must be accounted for extGain. */
INT_PCM pcmOutputBuffer[(8) * (1024 * 2)];
HANDLE_DRC_DECODER hUniDrcDecoder;
UCHAR multibandDrcPresent;
UCHAR numTimeSlots;
@ -427,7 +430,7 @@ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self,
\return error status
*/
LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
HANDLE_AACDECODER self, const UINT flags, FIXP_PCM *pTimeData,
HANDLE_AACDECODER self, const UINT flags, PCM_DEC *pTimeData,
const INT timeDataSize, const int timeDataChannelOffset);
/* Free config dependent AAC memory */

View File

@ -119,10 +119,10 @@ amm-info@iis.fraunhofer.de
/* Decoder library info */
#define AACDECODER_LIB_VL0 3
#define AACDECODER_LIB_VL1 1
#define AACDECODER_LIB_VL2 2
#define AACDECODER_LIB_VL1 2
#define AACDECODER_LIB_VL2 0
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
#ifdef __ANDROID__
#ifdef SUPPRESS_BUILD_DATE_INFO
#define AACDECODER_LIB_BUILD_DATE ""
#define AACDECODER_LIB_BUILD_TIME ""
#else
@ -1133,35 +1133,31 @@ static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) {
return n;
}
LINKSPEC_CPP AAC_DECODER_ERROR
aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
const INT timeDataSize_extern, const UINT flags) {
LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
INT_PCM *pTimeData,
const INT timeDataSize,
const UINT flags) {
AAC_DECODER_ERROR ErrorStatus;
INT layer;
INT nBits;
INT timeData2Size;
INT timeData3Size;
INT timeDataHeadroom;
HANDLE_FDK_BITSTREAM hBs;
int fTpInterruption = 0; /* Transport originated interruption detection. */
int fTpConceal = 0; /* Transport originated concealment. */
INT_PCM *pTimeData = NULL;
INT timeDataSize = 0;
UINT accessUnit = 0;
UINT numAccessUnits = 1;
UINT numPrerollAU = 0;
int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */
int applyCrossfade = 1; /* flag indicates if flushing was possible */
FIXP_PCM *pTimeDataFixpPcm; /* Signal buffer for decoding process before PCM
processing */
INT timeDataFixpPcmSize;
PCM_DEC *pTimeDataPcmPost; /* Signal buffer for PCM post-processing */
INT timeDataPcmPostSize;
int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */
int applyCrossfade = 1; /* flag indicates if flushing was possible */
PCM_DEC *pTimeData2;
PCM_AAC *pTimeData3;
if (self == NULL) {
return AAC_DEC_INVALID_HANDLE;
}
pTimeData = self->pcmOutputBuffer;
timeDataSize = sizeof(self->pcmOutputBuffer) / sizeof(*self->pcmOutputBuffer);
if (flags & AACDEC_INTR) {
self->streamInfo.numLostAccessUnits = 0;
}
@ -1271,9 +1267,9 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
}
/* Signal bit stream interruption to other modules if required. */
if (fTpInterruption || (flags & AACDEC_INTR)) {
if (fTpInterruption || ((flags & AACDEC_INTR) && (accessUnit == 0))) {
aacDecoder_SignalInterruption(self);
if (!(flags & AACDEC_INTR)) {
if (!((flags & AACDEC_INTR) && (accessUnit == 0))) {
ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR;
goto bail;
}
@ -1317,19 +1313,23 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
/* Use limiter configuration as requested. */
self->limiterEnableCurr = self->limiterEnableUser;
}
/* reset limiter gain on a per frame basis */
self->extGain[0] = FL2FXCONST_DBL(1.0f / (float)(1 << TDL_GAIN_SCALING));
pTimeDataFixpPcm = pTimeData;
timeDataFixpPcmSize = timeDataSize;
/* reset DRC level normalization gain on a per frame basis */
self->extGain[0] = AACDEC_DRC_GAIN_INIT_VALUE;
pTimeData2 = self->pTimeData2;
timeData2Size = self->timeData2Size / sizeof(PCM_DEC);
pTimeData3 = (PCM_AAC *)self->pTimeData2;
timeData3Size = self->timeData2Size / sizeof(PCM_AAC);
ErrorStatus = CAacDecoder_DecodeFrame(
self,
flags | (fTpConceal ? AACDEC_CONCEAL : 0) |
((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
: 0),
pTimeDataFixpPcm + 0, timeDataFixpPcmSize,
self->streamInfo.aacSamplesPerFrame + 0);
pTimeData2 + 0, timeData2Size, self->streamInfo.aacSamplesPerFrame + 0);
timeDataHeadroom = self->aacOutDataHeadroom;
/* if flushing for USAC DASH IPF was not possible go on with decoding
* preroll */
@ -1354,7 +1354,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
}
}
/* If the current pTimeDataFixpPcm does not contain a valid signal, there
/* If the current pTimeData2 does not contain a valid signal, there
* nothing else we can do, so bail. */
if (!IS_OUTPUT_VALID(ErrorStatus)) {
goto bail;
@ -1368,10 +1368,10 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
self->streamInfo.numChannels = self->streamInfo.aacNumChannels;
{
FDK_Delay_Apply(&self->usacResidualDelay,
pTimeDataFixpPcm +
1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0,
self->streamInfo.frameSize, 0);
FDK_Delay_Apply(
&self->usacResidualDelay,
pTimeData2 + 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0,
self->streamInfo.frameSize, 0);
}
/* Setting of internal MPS state; may be reset in CAacDecoder_SyncQmfMode
@ -1418,8 +1418,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
}
}
self->qmfDomain.globalConf.TDinput = pTimeData;
switch (FDK_QmfDomain_Configure(&self->qmfDomain)) {
default:
case QMF_DOMAIN_INIT_ERROR:
@ -1476,18 +1474,18 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF,
(self->mpsEnableCurr) ? 2 : 0);
INT_PCM *input;
input = (INT_PCM *)self->workBufferCore2;
FDKmemcpy(input, pTimeData,
sizeof(INT_PCM) * (self->streamInfo.numChannels) *
PCM_AAC *input;
input = (PCM_AAC *)self->workBufferCore2;
FDKmemcpy(input, pTimeData3,
sizeof(PCM_AAC) * (self->streamInfo.numChannels) *
(self->streamInfo.frameSize));
/* apply SBR processing */
sbrError = sbrDecoder_Apply(self->hSbrDecoder, input, pTimeData,
timeDataSize, &self->streamInfo.numChannels,
&self->streamInfo.sampleRate,
&self->mapDescr, self->chMapIndex,
self->frameOK, &self->psPossible);
sbrError = sbrDecoder_Apply(
self->hSbrDecoder, input, pTimeData3, timeData3Size,
&self->streamInfo.numChannels, &self->streamInfo.sampleRate,
&self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible,
self->aacOutDataHeadroom, &timeDataHeadroom);
if (sbrError == SBRDEC_OK) {
/* Update data in streaminfo structure. Assume that the SBR upsampling
@ -1566,10 +1564,11 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
if (err == 0) {
err = mpegSurroundDecoder_Apply(
(CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
(INT_PCM *)self->workBufferCore2, pTimeData, timeDataSize,
(PCM_AAC *)self->workBufferCore2, pTimeData3, timeData3Size,
self->streamInfo.aacSamplesPerFrame, &nChannels, &frameSize,
self->streamInfo.sampleRate, self->streamInfo.aot,
self->channelType, self->channelIndices, &self->mapDescr);
self->channelType, self->channelIndices, &self->mapDescr,
self->aacOutDataHeadroom, &timeDataHeadroom);
}
if (err == MPS_OUTPUT_BUFFER_TOO_SMALL) {
@ -1592,8 +1591,8 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
self->streamInfo.frameSize = self->mpsFrameSizeLast;
/* ... and clear output buffer so that potentially corrupted data does
* not reach the framework. */
FDKmemclear(pTimeData, self->mpsOutChannelsLast *
self->mpsFrameSizeLast * sizeof(INT_PCM));
FDKmemclear(pTimeData3, self->mpsOutChannelsLast *
self->mpsFrameSizeLast * sizeof(PCM_AAC));
/* Additionally proclaim that this frame had errors during decoding.
*/
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
@ -1614,11 +1613,11 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1);
/* apply SBR processing */
sbrError = sbrDecoder_Apply(self->hSbrDecoder, pTimeData, pTimeData,
timeDataSize, &self->streamInfo.numChannels,
&self->streamInfo.sampleRate,
&self->mapDescr, self->chMapIndex,
self->frameOK, &self->psPossible);
sbrError = sbrDecoder_Apply(
self->hSbrDecoder, pTimeData3, pTimeData3, timeData3Size,
&self->streamInfo.numChannels, &self->streamInfo.sampleRate,
&self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible,
self->aacOutDataHeadroom, &timeDataHeadroom);
if (sbrError == SBRDEC_OK) {
/* Update data in streaminfo structure. Assume that the SBR upsampling
@ -1646,17 +1645,15 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
}
}
/* Use dedicated memory for PCM postprocessing */
pTimeDataPcmPost = self->pTimeData2;
timeDataPcmPostSize = self->timeData2Size;
{
const int size =
self->streamInfo.frameSize * self->streamInfo.numChannels;
FDK_ASSERT(timeDataPcmPostSize >= size);
for (int i = 0; i < size; i++) {
pTimeDataPcmPost[i] =
(PCM_DEC)FX_PCM2PCM_DEC(pTimeData[i]) >> PCM_OUT_HEADROOM;
if ((INT)PCM_OUT_HEADROOM != timeDataHeadroom) {
for (int i = ((self->streamInfo.frameSize *
self->streamInfo.numChannels) -
1);
i >= 0; i--) {
pTimeData2[i] =
(PCM_DEC)pTimeData3[i] >> (PCM_OUT_HEADROOM - timeDataHeadroom);
}
}
}
@ -1711,22 +1708,21 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
if ((self->streamInfo.numChannels > 1) &&
(0 || (self->sbrEnabled) || (self->mpsEnableCurr))) {
/* interleaving/deinterleaving is performed on upper part of
* pTimeDataPcmPost. Check if this buffer is large enough. */
if (timeDataPcmPostSize <
(INT)(2 * self->streamInfo.numChannels *
self->streamInfo.frameSize * sizeof(PCM_DEC))) {
* pTimeData2. Check if this buffer is large enough. */
if (timeData2Size < (INT)(2 * self->streamInfo.numChannels *
self->streamInfo.frameSize)) {
ErrorStatus = AAC_DEC_UNKNOWN;
goto bail;
}
needsDeinterleaving = 1;
drcWorkBuffer =
(FIXP_DBL *)pTimeDataPcmPost +
(FIXP_DBL *)pTimeData2 +
self->streamInfo.numChannels * self->streamInfo.frameSize;
FDK_deinterleave(
pTimeDataPcmPost, drcWorkBuffer, self->streamInfo.numChannels,
pTimeData2, drcWorkBuffer, self->streamInfo.numChannels,
self->streamInfo.frameSize, self->streamInfo.frameSize);
} else {
drcWorkBuffer = (FIXP_DBL *)pTimeDataPcmPost;
drcWorkBuffer = pTimeData2;
}
/* prepare Loudness Normalisation gain */
@ -1761,16 +1757,51 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
if (needsDeinterleaving) {
FDK_interleave(
drcWorkBuffer, pTimeDataPcmPost, self->streamInfo.numChannels,
drcWorkBuffer, pTimeData2, self->streamInfo.numChannels,
self->streamInfo.frameSize, self->streamInfo.frameSize);
}
}
}
if (FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) {
/* return output loudness information for MPEG-D DRC */
LONG outputLoudness =
FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_OUTPUT_LOUDNESS);
if (outputLoudness == DRC_DEC_LOUDNESS_NOT_PRESENT) {
/* no valid MPEG-D DRC loudness value contained */
self->streamInfo.outputLoudness = -1;
} else {
if (outputLoudness > 0) {
/* positive output loudness values (very unusual) are limited to 0
* dB */
self->streamInfo.outputLoudness = 0;
} else {
self->streamInfo.outputLoudness =
-(INT)outputLoudness >>
22; /* negate and scale from e = 7 to e = (31-2) */
}
}
} else {
/* return output loudness information for MPEG-4 DRC */
if (self->streamInfo.drcProgRefLev <
0) { /* no MPEG-4 DRC loudness metadata contained */
self->streamInfo.outputLoudness = -1;
} else {
if (self->defaultTargetLoudness <
0) { /* loudness normalization is off */
self->streamInfo.outputLoudness = self->streamInfo.drcProgRefLev;
} else {
self->streamInfo.outputLoudness = self->defaultTargetLoudness;
}
}
}
if (self->streamInfo.extAot != AOT_AAC_SLS) {
INT pcmLimiterScale = 0;
INT interleaved = 0;
interleaved |= (self->sbrEnabled) ? 1 : 0;
interleaved |= (self->mpsEnableCurr) ? 1 : 0;
PCMDMX_ERROR dmxErr = PCMDMX_OK;
if (flags & (AACDEC_INTR)) {
if ((flags & AACDEC_INTR) && (accessUnit == 0)) {
/* delete data from the past (e.g. mixdown coeficients) */
pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
}
@ -1781,17 +1812,12 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
}
}
INT interleaved = 0;
interleaved |= (self->sbrEnabled) ? 1 : 0;
interleaved |= (self->mpsEnableCurr) ? 1 : 0;
/* do PCM post processing */
dmxErr = pcmDmx_ApplyFrame(
self->hPcmUtils, pTimeDataPcmPost, timeDataFixpPcmSize,
self->streamInfo.frameSize, &self->streamInfo.numChannels,
interleaved, self->channelType, self->channelIndices,
&self->mapDescr,
(self->limiterEnableCurr) ? &pcmLimiterScale : NULL);
dmxErr = pcmDmx_ApplyFrame(self->hPcmUtils, pTimeData2, timeData2Size,
self->streamInfo.frameSize,
&self->streamInfo.numChannels, interleaved,
self->channelType, self->channelIndices,
&self->mapDescr, &pcmLimiterScale);
if (dmxErr == PCMDMX_OUTPUT_BUFFER_TOO_SMALL) {
ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
goto bail;
@ -1803,13 +1829,35 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
}
pcmLimiterScale += PCM_OUT_HEADROOM;
if (flags & AACDEC_CLRHIST) {
if (!(self->flags[0] & AC_USAC)) {
/* Reset DRC data */
aacDecoder_drcReset(self->hDrcInfo);
/* Delete the delayed signal. */
pcmLimiter_Reset(self->hLimiter);
}
}
/* Set applyExtGain if DRC processing is enabled and if
progRefLevelPresent is present for the first time. Consequences: The
headroom of the output signal can be set to AACDEC_DRC_GAIN_SCALING
only for audio formats which support legacy DRC Level Normalization.
For all other audio formats the headroom of the output
signal is set to PCM_OUT_HEADROOM. */
if (self->hDrcInfo->enable &&
(self->hDrcInfo->progRefLevelPresent == 1)) {
self->hDrcInfo->applyExtGain |= 1;
}
/* Check whether time data buffer is large enough. */
if (timeDataSize <
(self->streamInfo.numChannels * self->streamInfo.frameSize)) {
ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
goto bail;
}
if (self->limiterEnableCurr) {
/* use workBufferCore2 buffer for interleaving */
PCM_LIM *pInterleaveBuffer;
@ -1818,44 +1866,72 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
/* Set actual signal parameters */
pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels);
pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate);
pcmLimiterScale += PCM_OUT_HEADROOM;
if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
(self->mpsEnableCurr)) {
pInterleaveBuffer = (PCM_LIM *)pTimeDataPcmPost;
pInterleaveBuffer = (PCM_LIM *)pTimeData2;
} else {
pInterleaveBuffer = (PCM_LIM *)pTimeData;
pInterleaveBuffer = (PCM_LIM *)self->workBufferCore2;
/* applyLimiter requests for interleaved data */
/* Interleave ouput buffer */
FDK_interleave(pTimeDataPcmPost, pInterleaveBuffer,
FDK_interleave(pTimeData2, pInterleaveBuffer,
self->streamInfo.numChannels, blockLength,
self->streamInfo.frameSize);
}
FIXP_DBL *pGainPerSample = NULL;
if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) {
pGainPerSample = self->workBufferCore1;
if ((INT)GetRequiredMemWorkBufferCore1() <
(INT)(self->streamInfo.frameSize * sizeof(FIXP_DBL))) {
ErrorStatus = AAC_DEC_UNKNOWN;
goto bail;
}
pcmLimiterScale = applyDrcLevelNormalization(
self->hDrcInfo, (PCM_DEC *)pInterleaveBuffer, self->extGain,
pGainPerSample, pcmLimiterScale, self->extGainDelay,
self->streamInfo.frameSize, self->streamInfo.numChannels, 1, 1);
}
pcmLimiter_Apply(self->hLimiter, pInterleaveBuffer, pTimeData,
self->extGain, &pcmLimiterScale, 1,
self->extGainDelay, self->streamInfo.frameSize);
pGainPerSample, pcmLimiterScale,
self->streamInfo.frameSize);
{
/* Announce the additional limiter output delay */
self->streamInfo.outputDelay += pcmLimiter_GetDelay(self->hLimiter);
}
} else {
if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) {
pcmLimiterScale = applyDrcLevelNormalization(
self->hDrcInfo, pTimeData2, self->extGain, NULL,
pcmLimiterScale, self->extGainDelay, self->streamInfo.frameSize,
self->streamInfo.numChannels,
(interleaved || (self->streamInfo.numChannels == 1))
? 1
: self->streamInfo.frameSize,
0);
}
/* If numChannels = 1 we do not need interleaving. The same applies if
SBR or MPS are used, since their output is interleaved already
(resampled or not) */
if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
(self->mpsEnableCurr)) {
scaleValuesSaturate(
pTimeData, pTimeDataPcmPost,
pTimeData, pTimeData2,
self->streamInfo.frameSize * self->streamInfo.numChannels,
PCM_OUT_HEADROOM);
pcmLimiterScale);
} else {
scaleValuesSaturate(
(INT_PCM *)self->workBufferCore2, pTimeDataPcmPost,
(INT_PCM *)self->workBufferCore2, pTimeData2,
self->streamInfo.frameSize * self->streamInfo.numChannels,
PCM_OUT_HEADROOM);
pcmLimiterScale);
/* Interleave ouput buffer */
FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData,
self->streamInfo.numChannels,
@ -1951,20 +2027,8 @@ bail:
ErrorStatus = AAC_DEC_UNKNOWN;
}
/* Check whether external output buffer is large enough. */
if (timeDataSize_extern <
self->streamInfo.numChannels * self->streamInfo.frameSize) {
ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
}
/* Update external output buffer. */
if (IS_OUTPUT_VALID(ErrorStatus)) {
FDKmemcpy(pTimeData_extern, pTimeData,
self->streamInfo.numChannels * self->streamInfo.frameSize *
sizeof(*pTimeData));
} else {
FDKmemclear(pTimeData_extern,
timeDataSize_extern * sizeof(*pTimeData_extern));
if (!IS_OUTPUT_VALID(ErrorStatus)) {
FDKmemclear(pTimeData, timeDataSize * sizeof(*pTimeData));
}
return ErrorStatus;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -1015,9 +1015,9 @@ FIXP_DBL get_gain(const FIXP_DBL *x, const FIXP_DBL *y, int n) {
void CBlock_FrequencyToTime(
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1,
UINT elFlags, INT elCh) {
const INT aacOutDataHeadroom, UINT elFlags, INT elCh) {
int fr, fl, tl, nSpec;
#if defined(FDK_ASSERT_ENABLE)
@ -1213,6 +1213,7 @@ void CBlock_FrequencyToTime(
bass_pf_1sf_delay(p2_synth, pitch, pit_gain, frameLen,
(LpdSfd + 2) * L_SUBFR + BPF_SFD * L_SUBFR,
frameLen - (LpdSfd + 4) * L_SUBFR, outSamples,
aacOutDataHeadroom,
pAacDecoderStaticChannelInfo->mem_bpf);
}
@ -1236,7 +1237,8 @@ void CBlock_FrequencyToTime(
? MLT_FLAG_CURR_ALIAS_SYMMETRY
: 0);
scaleValuesSaturate(outSamples, tmp, frameLen, MDCT_OUT_HEADROOM);
scaleValuesSaturate(outSamples, tmp, frameLen,
MDCT_OUT_HEADROOM - aacOutDataHeadroom);
}
}
@ -1251,7 +1253,7 @@ void CBlock_FrequencyToTime(
#include "ldfiltbank.h"
void CBlock_FrequencyToTimeLowDelay(
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
const short frameLen) {
InvMdctTransformLowDelay_fdk(
SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -218,16 +218,16 @@ void ApplyTools(CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
*/
void CBlock_FrequencyToTime(
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1,
UINT elFlags, INT elCh);
const INT aacOutDataHeadroom, UINT elFlags, INT elCh);
/**
* \brief Transform double lapped MDCT (AAC-ELD) spectral data into time domain.
*/
void CBlock_FrequencyToTimeLowDelay(
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
const short frameLen);
AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -226,7 +226,7 @@ static void CConcealment_ApplyRandomSign(int iRandomPhase, FIXP_DBL *spec,
/* TimeDomainFading */
static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
FIXP_DBL fadeStop, FIXP_PCM *pcmdata);
FIXP_DBL fadeStop, PCM_DEC *pcmdata);
static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
int *fadingSteps,
FIXP_DBL fadeStop,
@ -242,7 +242,9 @@ static int CConcealment_ApplyFadeOut(
static int CConcealment_TDNoise_Random(ULONG *seed);
static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
const int len, FIXP_PCM *const pcmdata);
const int len,
const INT aacOutDataHeadroom,
PCM_DEC *const pcmdata);
static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) {
BLOCK_TYPE newWinSeq = BLOCK_LONG;
@ -1228,7 +1230,6 @@ static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
int sfb, line = 0;
int fac_shift;
int fac_mod;
FIXP_DBL accu;
for (sfb = 0; sfb < sfbCnt; sfb++) {
fac_shift =
@ -1236,15 +1237,11 @@ static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
fac_mod = fac_shift & 3;
fac_shift = (fac_shift >> 2) + 1;
fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct);
fac_shift = fMax(fMin(fac_shift, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
for (; line < pSfbOffset[sfb + 1]; line++) {
accu = fMult(*(spectrum + line), facMod4Table[fac_mod]);
if (fac_shift < 0) {
accu >>= -fac_shift;
} else {
accu <<= fac_shift;
}
*(spectrum + line) = accu;
FIXP_DBL accu = fMult(*(spectrum + line), facMod4Table[fac_mod]);
*(spectrum + line) = scaleValue(accu, fac_shift);
}
}
*pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct);
@ -1618,7 +1615,7 @@ static void CConcealment_ApplyRandomSign(int randomPhase, FIXP_DBL *spec,
}
if (packedSign & 0x1) {
spec[i] = -spec[i];
spec[i] = -fMax(spec[i], (FIXP_DBL)(MINVAL_DBL + 1));
}
packedSign >>= 1;
@ -1849,7 +1846,7 @@ Target fading level is determined by fading index cntFadeFrames.
INT CConcealment_TDFading(
int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1) {
const INT aacOutDataHeadroom, PCM_DEC *pcmdata, PCM_DEC *pcmdata_1) {
/*
Do the fading in Time domain based on concealment states and core mode
*/
@ -1962,7 +1959,8 @@ INT CConcealment_TDFading(
start += len;
}
}
CConcealment_TDNoise_Apply(pConcealmentInfo, len, pcmdata);
CConcealment_TDNoise_Apply(pConcealmentInfo, len, aacOutDataHeadroom,
pcmdata);
/* Save end-of-frame attenuation and fading type */
pConcealmentInfo->lastFadingType = fadingType;
@ -1974,12 +1972,11 @@ INT CConcealment_TDFading(
/* attenuate pcmdata in Time Domain Fading process */
static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
FIXP_DBL fadeStop, FIXP_PCM *pcmdata) {
FIXP_DBL fadeStop, PCM_DEC *pcmdata) {
int i;
FIXP_DBL dStep;
FIXP_DBL dGain;
FIXP_DBL dGain_apply;
int bitshift = (DFRACT_BITS - SAMPLE_BITS);
/* set start energy */
dGain = fadeStart;
@ -1992,7 +1989,7 @@ static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
*/
dGain_apply = fMax((FIXP_DBL)0, dGain);
/* finally, attenuate samples */
pcmdata[i] = (FIXP_PCM)((fMult(pcmdata[i], (dGain_apply))) >> bitshift);
pcmdata[i] = FIXP_DBL2PCM_DEC(fMult(pcmdata[i], dGain_apply));
}
}
@ -2055,9 +2052,11 @@ static int CConcealment_TDNoise_Random(ULONG *seed) {
}
static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
const int len, FIXP_PCM *const pcmdata) {
FIXP_PCM *states = pConcealmentInfo->TDNoiseStates;
FIXP_PCM noiseVal;
const int len,
const INT aacOutDataHeadroom,
PCM_DEC *const pcmdata) {
PCM_DEC *states = pConcealmentInfo->TDNoiseStates;
PCM_DEC noiseVal;
FIXP_DBL noiseValLong;
FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef;
FIXP_DBL TDNoiseAtt;
@ -2075,18 +2074,20 @@ static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
/* create filtered noise */
states[2] = states[1];
states[1] = states[0];
states[0] = ((FIXP_PCM)CConcealment_TDNoise_Random(&seed));
states[0] =
FIXP_DBL2PCM_DEC((FIXP_DBL)CConcealment_TDNoise_Random(&seed));
noiseValLong = fMult(states[0], coef[0]) + fMult(states[1], coef[1]) +
fMult(states[2], coef[2]);
noiseVal = FX_DBL2FX_PCM(fMult(noiseValLong, TDNoiseAtt));
noiseVal = FIXP_DBL2PCM_DEC(fMult(noiseValLong, TDNoiseAtt) >>
aacOutDataHeadroom);
/* add filtered noise - check for clipping, before */
if (noiseVal > (FIXP_PCM)0 &&
pcmdata[ii] > (FIXP_PCM)MAXVAL_FIXP_PCM - noiseVal) {
noiseVal = noiseVal * (FIXP_PCM)-1;
} else if (noiseVal < (FIXP_PCM)0 &&
pcmdata[ii] < (FIXP_PCM)MINVAL_FIXP_PCM - noiseVal) {
noiseVal = noiseVal * (FIXP_PCM)-1;
if (noiseVal > (PCM_DEC)0 &&
pcmdata[ii] > (PCM_DEC)MAXVAL_PCM_DEC - noiseVal) {
noiseVal = noiseVal * (PCM_DEC)-1;
} else if (noiseVal < (PCM_DEC)0 &&
pcmdata[ii] < (PCM_DEC)MINVAL_PCM_DEC - noiseVal) {
noiseVal = noiseVal * (PCM_DEC)-1;
}
pcmdata[ii] += noiseVal;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -147,6 +147,6 @@ int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo,
INT CConcealment_TDFading(
int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1);
const INT aacOutDataHeadroom, PCM_DEC *pcmdata, PCM_DEC *pcmdata_1);
#endif /* #ifndef CONCEAL_H */

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -194,7 +194,7 @@ typedef struct {
FIXP_DBL last_tcx_gain;
INT last_tcx_gain_e;
ULONG TDNoiseSeed;
FIXP_PCM TDNoiseStates[3];
PCM_DEC TDNoiseStates[3];
FIXP_SGL TDNoiseCoef[3];
FIXP_SGL TDNoiseAtt;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -112,17 +112,20 @@ amm-info@iis.fraunhofer.de
#if defined(__arm__)
#endif
static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
static void multE2_DinvF_fdk(PCM_DEC *output, FIXP_DBL *x, const FIXP_WTB *fb,
FIXP_DBL *z, const int N) {
int i;
/* scale for FIXP_DBL -> INT_PCM conversion. */
const int scale = (DFRACT_BITS - SAMPLE_BITS) - LDFB_HEADROOM;
#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
/* scale for FIXP_DBL -> PCM_DEC conversion: */
const int scale = (DFRACT_BITS - PCM_OUT_BITS) - LDFB_HEADROOM + (3);
#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0)
FIXP_DBL rnd_val_wts0 = (FIXP_DBL)0;
FIXP_DBL rnd_val_wts1 = (FIXP_DBL)0;
#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - WTS0 - 1) > 0)
if (-WTS0 - 1 + scale)
rnd_val_wts0 = (FIXP_DBL)(1 << (-WTS0 - 1 + scale - 1));
#endif
if (-WTS1 - 1 + scale)
rnd_val_wts1 = (FIXP_DBL)(1 << (-WTS1 - 1 + scale - 1));
#endif
@ -131,24 +134,26 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
FIXP_DBL z0, z2, tmp;
z2 = x[N / 2 + i];
z0 = z2 + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1));
z0 = fAddSaturate(z2,
(fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1)));
z[N / 2 + i] = x[N / 2 - 1 - i] +
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1));
z[N / 2 + i] = fAddSaturate(
x[N / 2 - 1 - i],
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1)));
tmp = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) +
fMultDiv2(z[i], fb[N + N / 2 + i]));
#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0)
FDK_ASSERT((-WTS1 - 1 + scale) >= 0);
FDK_ASSERT(tmp <= ((FIXP_DBL)0x7FFFFFFF -
rnd_val_wts1)); /* rounding must not cause overflow */
output[(N * 3 / 4 - 1 - i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
output[(N * 3 / 4 - 1 - i)] = (PCM_DEC)SATURATE_RIGHT_SHIFT(
tmp + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS);
#else
FDK_ASSERT((WTS1 + 1 - scale) >= 0);
output[(N * 3 / 4 - 1 - i)] =
(FIXP_PCM)SATURATE_LEFT_SHIFT(tmp, WTS1 + 1 - scale, PCM_OUT_BITS);
(PCM_DEC)SATURATE_LEFT_SHIFT(tmp, WTS1 + 1 - scale, PCM_OUT_BITS);
#endif
z[i] = z0;
@ -159,32 +164,34 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
FIXP_DBL z0, z2, tmp0, tmp1;
z2 = x[N / 2 + i];
z0 = z2 + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1));
z0 = fAddSaturate(z2,
(fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1)));
z[N / 2 + i] = x[N / 2 - 1 - i] +
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1));
z[N / 2 + i] = fAddSaturate(
x[N / 2 - 1 - i],
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1)));
tmp0 = (fMultDiv2(z[N / 2 + i], fb[N / 2 - 1 - i]) +
fMultDiv2(z[i], fb[N / 2 + i]));
tmp1 = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) +
fMultDiv2(z[i], fb[N + N / 2 + i]));
#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0)
FDK_ASSERT((-WTS0 - 1 + scale) >= 0);
FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF -
rnd_val_wts0)); /* rounding must not cause overflow */
FDK_ASSERT(tmp1 <= ((FIXP_DBL)0x7FFFFFFF -
rnd_val_wts1)); /* rounding must not cause overflow */
output[(i - N / 4)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
output[(i - N / 4)] = (PCM_DEC)SATURATE_RIGHT_SHIFT(
tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS);
output[(N * 3 / 4 - 1 - i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
output[(N * 3 / 4 - 1 - i)] = (PCM_DEC)SATURATE_RIGHT_SHIFT(
tmp1 + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS);
#else
FDK_ASSERT((WTS0 + 1 - scale) >= 0);
output[(i - N / 4)] =
(FIXP_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS);
(PCM_DEC)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS);
output[(N * 3 / 4 - 1 - i)] =
(FIXP_PCM)SATURATE_LEFT_SHIFT(tmp1, WTS1 + 1 - scale, PCM_OUT_BITS);
(PCM_DEC)SATURATE_LEFT_SHIFT(tmp1, WTS1 + 1 - scale, PCM_OUT_BITS);
#endif
z[i] = z0;
z[N + i] = z2;
@ -194,22 +201,22 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
for (i = 0; i < N / 4; i++) {
FIXP_DBL tmp0 = fMultDiv2(z[i], fb[N / 2 + i]);
#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0)
FDK_ASSERT((-WTS0 - 1 + scale) >= 0);
FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF -
rnd_val_wts0)); /* rounding must not cause overflow */
output[(N * 3 / 4 + i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
output[(N * 3 / 4 + i)] = (PCM_DEC)SATURATE_RIGHT_SHIFT(
tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS);
#else
FDK_ASSERT((WTS0 + 1 - scale) >= 0);
output[(N * 3 / 4 + i)] =
(FIXP_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS);
(PCM_DEC)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS);
#endif
}
}
int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctData, const int mdctData_e,
FIXP_PCM *output, FIXP_DBL *fs_buffer,
PCM_DEC *output, FIXP_DBL *fs_buffer,
const int N) {
const FIXP_WTB *coef;
FIXP_DBL gain = (FIXP_DBL)0;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -104,9 +104,10 @@ amm-info@iis.fraunhofer.de
#define LDFILTBANK_H
#include "common_fix.h"
#include "aac_rom.h"
int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctdata_m, const int mdctdata_e,
FIXP_PCM *mdctOut, FIXP_DBL *fs_buffer,
PCM_DEC *mdctOut, FIXP_DBL *fs_buffer,
const int frameLength);
#endif

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -807,19 +807,17 @@ void CJointStereo_ApplyMS(
for (int i = 0; i < windowLen; i++) {
dmx_re_prev[i] =
((staticSpectralCoeffsL[index_offset + i] >>
srLeftChan) +
fMin(DFRACT_BITS - 1, srLeftChan + 1)) +
(staticSpectralCoeffsR[index_offset + i] >>
srRightChan)) >>
1;
fMin(DFRACT_BITS - 1, srRightChan + 1)));
}
} else {
for (int i = 0; i < windowLen; i++) {
dmx_re_prev[i] =
((staticSpectralCoeffsL[index_offset + i] >>
srLeftChan) -
fMin(DFRACT_BITS - 1, srLeftChan + 1)) -
(staticSpectralCoeffsR[index_offset + i] >>
srRightChan)) >>
1;
fMin(DFRACT_BITS - 1, srRightChan + 1)));
}
}
}
@ -854,12 +852,13 @@ void CJointStereo_ApplyMS(
if (window == 0) {
if (dmx_re_prev_e < frameMaxScale) {
if (mainband_flag == 0) {
scaleValues(dmx_re_prev, store_dmx_re_prev, windowLen,
-(frameMaxScale - dmx_re_prev_e));
scaleValues(
dmx_re_prev, store_dmx_re_prev, windowLen,
-fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e)));
} else {
for (int i = 0; i < windowLen; i++) {
dmx_re_prev[i] >>= (frameMaxScale - dmx_re_prev_e);
}
scaleValues(
dmx_re_prev, windowLen,
-fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e)));
}
} else {
if (mainband_flag == 0) {
@ -873,10 +872,9 @@ void CJointStereo_ApplyMS(
FDK_ASSERT(pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
BLOCK_SHORT);
if (specScaleL[window - 1] < frameMaxScale) {
for (int i = 0; i < windowLen; i++) {
dmx_re[windowLen * (window - 1) + i] >>=
(frameMaxScale - specScaleL[window - 1]);
}
scaleValues(&dmx_re[windowLen * (window - 1)], windowLen,
-fMin(DFRACT_BITS - 1,
(frameMaxScale - specScaleL[window - 1])));
} else {
specScaleL[window] = specScaleL[window - 1];
specScaleR[window] = specScaleR[window - 1];
@ -991,7 +989,7 @@ void CJointStereo_ApplyMS(
} /* if ( pJointStereoData->complex_coef == 1 ) */
/* 4. upmix process */
INT pred_dir = cplxPredictionData->pred_dir ? -1 : 1;
LONG pred_dir = cplxPredictionData->pred_dir ? -1 : 1;
/* 0.1 in Q-3.34 */
const FIXP_DBL pointOne = 0x66666666; /* 0.8 */
/* Shift value for the downmix */
@ -1041,34 +1039,24 @@ void CJointStereo_ApplyMS(
the downmix. "dmx_re" and "specL" are two different pointers
pointing to separate arrays, which may or may not contain the
same data (with different scaling).
specL[i] = + (specL[i] + side);
specR[i] = -/+ (specL[i] - side);
*/
FIXP_DBL side, left, right;
/* help1: alpha_re[i] * dmx_re[i] */
FIXP_DBL help1 = fMultDiv2(alpha_re_tmp, *p2dmxRe++);
side = fMultAddDiv2(fMultDiv2(alpha_re_tmp, *p2dmxRe++),
alpha_im_tmp, (*p2dmxIm++) << shift_dmx);
side = ((*p2CoeffR) >> 2) -
(FIXP_DBL)SATURATE_SHIFT(side, -(help3_shift - 2),
DFRACT_BITS - 2);
/* tmp: dmx_im[i] */
FIXP_DBL tmp = (*p2dmxIm++) << shift_dmx;
left = ((*p2CoeffL) >> 2) + side;
right = ((*p2CoeffL) >> 2) - side;
right = (FIXP_DBL)((LONG)right * pred_dir);
/* help2: alpha_im[i] * dmx_im[i] */
FIXP_DBL help2 = fMultDiv2(alpha_im_tmp, tmp);
/* help3: alpha_re[i] * dmx_re[i] + alpha_im[i] * dmx_im[i] */
FIXP_DBL help3 = help1 + help2;
/* side (= help4) = specR[i] - (dmx_re[i] * specL[i] + alpha_im[i]
* * dmx_im[i]) */
FIXP_DBL help4 = *p2CoeffR - scaleValue(help3, help3_shift);
/* We calculate the left and right output by using the helper
* function */
/* specR[i] = -/+ (specL[i] - side); */
*p2CoeffR =
(FIXP_DBL)((LONG)(*p2CoeffL - help4) * (LONG)pred_dir);
p2CoeffR++;
/* specL[i] = specL[i] + side; */
*p2CoeffL = *p2CoeffL + help4;
p2CoeffL++;
*p2CoeffL++ = SATURATE_LEFT_SHIFT_ALT(left, 2, DFRACT_BITS);
*p2CoeffR++ = SATURATE_LEFT_SHIFT_ALT(right, 2, DFRACT_BITS);
}
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -131,7 +131,7 @@ void E_UTIL_preemph(const FIXP_DBL *in, FIXP_DBL *out, INT L) {
int i;
for (i = 0; i < L; i++) {
out[i] = in[i] - fMult(PREEMPH_FAC, in[i - 1]);
out[i] = fAddSaturate(in[i], -fMult(PREEMPH_FAC, in[i - 1]));
}
return;
@ -465,7 +465,9 @@ void BuildAdaptiveExcitation(
/* Note: code[L_SUBFR] and exc2[L_SUBFR] share the same memory!
If exc2[i] is written, code[i] will be destroyed!
*/
#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC)
#define SF_HEADROOM (1)
#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC - SF_HEADROOM)
#define SF_GAIN_P2 (SF_GAIN_P - SF_HEADROOM)
int i;
FIXP_DBL tmp, cpe, code_smooth_prev, code_smooth;
@ -477,8 +479,8 @@ void BuildAdaptiveExcitation(
cpe = (period_fac >> (2 - SF_PFAC)) + FL2FXCONST_DBL(0.25f);
/* u'(n) */
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1); /* v(0)*g_p */
*exc++ = tmp + (fMultDiv2(code[0], gain_code) << SF);
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1); /* v(0)*g_p */
*exc++ = (tmp + (fMultDiv2(code[0], gain_code) << SF)) << SF_HEADROOM;
/* u(n) */
code_smooth_prev = fMultDiv2(*code++, gain_code_smoothed)
@ -487,15 +489,15 @@ void BuildAdaptiveExcitation(
code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF; /* c(1) * g_sc */
tmp += code_smooth_prev; /* tmp = v(0)*g_p + c(0)*g_sc */
cpe_code_smooth = fMultDiv2(cpe, code_smooth);
*exc2++ = tmp - cpe_code_smooth;
*exc2++ = (tmp - cpe_code_smooth) << SF_HEADROOM;
cpe_code_smooth_prev = fMultDiv2(cpe, code_smooth_prev);
i = L_SUBFR - 2;
do /* ARM926: 22 cycles per iteration */
{
/* u'(n) */
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
*exc++ = tmp + (fMultDiv2(code_i, gain_code) << SF);
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1);
*exc++ = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;
/* u(n) */
tmp += code_smooth; /* += g_sc * c(i) */
tmp -= cpe_code_smooth_prev;
@ -503,16 +505,17 @@ void BuildAdaptiveExcitation(
code_i = *code++;
code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF;
cpe_code_smooth = fMultDiv2(cpe, code_smooth);
*exc2++ = tmp - cpe_code_smooth; /* tmp - c_pe * g_sc * c(i+1) */
*exc2++ = (tmp - cpe_code_smooth)
<< SF_HEADROOM; /* tmp - c_pe * g_sc * c(i+1) */
} while (--i != 0);
/* u'(n) */
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
*exc = tmp + (fMultDiv2(code_i, gain_code) << SF);
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1);
*exc = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;
/* u(n) */
tmp += code_smooth;
tmp -= cpe_code_smooth_prev;
*exc2++ = tmp;
*exc2++ = tmp << SF_HEADROOM;
return;
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -344,7 +344,7 @@ INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac,
/* Overlap Add */
x0 = -fMult(*pOvl--, pWindow[i].v.re);
*pOut0 += IMDCT_SCALE_DBL(x0);
*pOut0 = fAddSaturate(*pOut0, IMDCT_SCALE_DBL(x0));
pOut0++;
}
} else {
@ -354,7 +354,7 @@ INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac,
/* Overlap Add */
x0 = fMult(*pOvl--, pWindow[i].v.re);
*pOut0 += IMDCT_SCALE_DBL(x0);
*pOut0 = fAddSaturate(*pOut0, IMDCT_SCALE_DBL(x0));
pOut0++;
}
}
@ -362,7 +362,7 @@ INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac,
0) { /* this should only happen for ACELP -> TCX20 -> ACELP transition */
FIXP_DBL *pOut = pOut0 - fl / 2; /* fl/2 == fac_length */
for (i = 0; i < fl / 2; i++) {
pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
pOut[i] = fAddSaturate(pOut[i], IMDCT_SCALE_DBL(hMdct->pFacZir[i]));
}
hMdct->pFacZir = NULL;
}
@ -493,9 +493,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
/* Div2 is compensated by table scaling */
x = fMultDiv2(pTmp2[i], FacWindowZir[w]);
x += fMultDiv2(pTmp1[-i - 1], FacWindowSynth[w]);
x += pFAC_and_FAC_ZIR[i];
pOut1[i] = x;
pOut1[i] = fAddSaturate(x, pFAC_and_FAC_ZIR[i]);
w++;
}
}
@ -552,7 +550,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
pOut1 < hMdct->overlap.time + hMdct->ov_size) ||
(pOut1 >= output && pOut1 < output + 1024));
*pOut1 += IMDCT_SCALE_DBL(-x1);
*pOut1 = fAddSaturate(*pOut1, IMDCT_SCALE_DBL(-x1));
pOut1--;
}
@ -578,7 +576,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
FIXP_DBL x = -(*pCurr--);
/* 5) (item 4) Synthesis filter Zir component, FAC ZIR (another one). */
if (i < f_len) {
x += *pF++;
x = fAddSaturate(x, *pF++);
}
FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
@ -668,9 +666,9 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
for (i = 0; i < fl / 2; i++) {
FIXP_DBL x0, x1;
cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
*pOut0 = IMDCT_SCALE_DBL(x0);
*pOut1 = IMDCT_SCALE_DBL(-x1);
cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
*pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
*pOut1 = IMDCT_SCALE_DBL_LSH1(-x1);
pOut0++;
pOut1--;
}
@ -680,9 +678,9 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
for (i = 0; i < fl / 2; i++) {
FIXP_DBL x0, x1;
cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
*pOut0 = IMDCT_SCALE_DBL(x0);
*pOut1 = IMDCT_SCALE_DBL(x1);
cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
*pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
*pOut1 = IMDCT_SCALE_DBL_LSH1(x1);
pOut0++;
pOut1--;
}
@ -691,9 +689,9 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
for (i = 0; i < fl / 2; i++) {
FIXP_DBL x0, x1;
cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow_prev[i]);
*pOut0 = IMDCT_SCALE_DBL(x0);
*pOut1 = IMDCT_SCALE_DBL(x1);
cplxMultDiv2(&x1, &x0, *pCurr++, *pOvl--, pWindow_prev[i]);
*pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
*pOut1 = IMDCT_SCALE_DBL_LSH1(x1);
pOut0++;
pOut1--;
}
@ -705,7 +703,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
FIXP_DBL *pOut = pOut0 - fl / 2;
FDK_ASSERT(fl / 2 <= 128);
for (i = 0; i < fl / 2; i++) {
pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
pOut[i] = fAddSaturate(pOut[i], IMDCT_SCALE_DBL(hMdct->pFacZir[i]));
}
hMdct->pFacZir = NULL;
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -231,7 +231,7 @@ void nearest_neighbor_2D8(FIXP_ZF x[8], int y[8]) {
void RE8_PPV(FIXP_ZF x[], SHORT y[], int r) {
int i, y0[8], y1[8];
FIXP_ZF x1[8], tmp;
FIXP_DBL e;
INT64 e;
/* find the nearest neighbor y0 of x in 2D8 */
nearest_neighbor_2D8(x, y0);
@ -245,16 +245,16 @@ void RE8_PPV(FIXP_ZF x[], SHORT y[], int r) {
}
/* compute e0=||x-y0||^2 and e1=||x-y1||^2 */
e = (FIXP_DBL)0;
e = 0;
for (i = 0; i < 8; i++) {
tmp = x[i] - INT2ZF(y0[i], 0);
e += fPow2Div2(
e += (INT64)fPow2Div2(
tmp << r); /* shift left to ensure that no fract part bits get lost. */
tmp = x[i] - INT2ZF(y1[i], 0);
e -= fPow2Div2(tmp << r);
e -= (INT64)fPow2Div2(tmp << r);
}
/* select best candidate y0 or y1 to minimize distortion */
if (e < (FIXP_DBL)0) {
if (e < 0) {
for (i = 0; i < 8; i++) {
y[i] = y0[i];
}
@ -565,7 +565,8 @@ static void lsf_weight_2st(FIXP_LPC *lsfq, FIXP_DBL *xq, int nk_mode) {
/* add non-weighted residual LSF vector to LSF1st */
for (i = 0; i < M_LP_FILTER_ORDER; i++) {
w = (LONG)fMultDiv2(factor, sqrtFixp(fMult(d[i], d[i + 1])));
lsfq[i] = fAddSaturate(lsfq[i], FX_DBL2FX_LPC((FIXP_DBL)(w * (LONG)xq[i])));
lsfq[i] = fAddSaturate(lsfq[i],
FX_DBL2FX_LPC((FIXP_DBL)((INT64)w * (LONG)xq[i])));
}
return;
@ -1138,9 +1139,12 @@ static void get_lsppol(FIXP_LPC lsp[], FIXP_DBL f[], int n, int flag) {
for (i = 2; i <= n; i++) {
plsp += 2;
b = -FX_LPC2FX_DBL(*plsp);
f[i] = ((fMultDiv2(b, f[i - 1]) << 1) + (f[i - 2])) << 1;
f[i] = SATURATE_LEFT_SHIFT((fMultDiv2(b, f[i - 1]) + (f[i - 2] >> 1)), 2,
DFRACT_BITS);
for (j = i - 1; j > 1; j--) {
f[j] = f[j] + (fMultDiv2(b, f[j - 1]) << 2) + f[j - 2];
f[j] = SATURATE_LEFT_SHIFT(
((f[j] >> 2) + fMultDiv2(b, f[j - 1]) + (f[j - 2] >> 2)), 2,
DFRACT_BITS);
}
f[1] = f[1] + (b >> (SF_F - 1));
}
@ -1167,6 +1171,9 @@ void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp) {
/*-----------------------------------------------------*
* Multiply F1(z) by (1+z^-1) and F2(z) by (1-z^-1) *
*-----------------------------------------------------*/
scaleValues(f1, NC + 1, -2);
scaleValues(f2, NC + 1, -2);
for (i = NC; i > 0; i--) {
f1[i] += f1[i - 1];
f2[i] -= f2[i - 1];
@ -1175,13 +1182,8 @@ void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp) {
FIXP_DBL aDBL[M_LP_FILTER_ORDER];
for (i = 1, k = M_LP_FILTER_ORDER - 1; i <= NC; i++, k--) {
FIXP_DBL tmp1, tmp2;
tmp1 = f1[i] >> 1;
tmp2 = f2[i] >> 1;
aDBL[i - 1] = (tmp1 + tmp2);
aDBL[k] = (tmp1 - tmp2);
aDBL[i - 1] = f1[i] + f2[i];
aDBL[k] = f1[i] - f2[i];
}
int headroom_a = getScalefactor(aDBL, M_LP_FILTER_ORDER);
@ -1190,5 +1192,5 @@ void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp) {
a[i] = FX_DBL2FX_LPC(aDBL[i] << headroom_a);
}
*a_exp = 8 - headroom_a;
*a_exp = SF_F + (2 - 1) - headroom_a;
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -122,17 +122,21 @@ amm-info@iis.fraunhofer.de
#include "ac_arith_coder.h"
void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
const FIXP_SGL *filt, INT stop, int len) {
void filtLP(const FIXP_DBL *syn, PCM_DEC *syn_out, FIXP_DBL *noise,
const FIXP_SGL *filt, const INT aacOutDataHeadroom, INT stop,
int len) {
INT i, j;
FIXP_DBL tmp;
FDK_ASSERT((aacOutDataHeadroom - 1) >= -(MDCT_OUTPUT_SCALE));
for (i = 0; i < stop; i++) {
tmp = fMultDiv2(noise[i], filt[0]); // Filt in Q-1.16
for (j = 1; j <= len; j++) {
tmp += fMultDiv2((noise[i - j] + noise[i + j]), filt[j]);
tmp += fMult((noise[i - j] >> 1) + (noise[i + j] >> 1), filt[j]);
}
syn_out[i] = (FIXP_PCM)(IMDCT_SCALE(syn[i] - tmp));
syn_out[i] = (PCM_DEC)(
IMDCT_SCALE((syn[i] >> 1) - (tmp >> 1), aacOutDataHeadroom - 1));
}
}
@ -142,8 +146,10 @@ void bass_pf_1sf_delay(
FIXP_DBL *pit_gain,
const int frame_length, /* (i) : frame length (should be 768|1024) */
const INT l_frame,
const INT l_next, /* (i) : look ahead for symmetric filtering */
FIXP_PCM *synth_out, /* (o) : filtered synthesis (with delay of 1 subfr) */
const INT l_next, /* (i) : look ahead for symmetric filtering */
PCM_DEC *synth_out, /* (o) : filtered synthesis (with delay of 1 subfr) */
const INT aacOutDataHeadroom, /* (i) : headroom of the output time signal to
prevent clipping */
FIXP_DBL mem_bpf[]) /* i/o : memory state [L_FILT+L_SUBFR] */
{
INT i, sf, i_subfr, T, T2, lg;
@ -335,17 +341,22 @@ void bass_pf_1sf_delay(
{
for (i = 0; i < lg; i++) {
/* scaled with SF_SYNTH + gain_sf + 1 */
/* scaled with SF_SYNTH + gain_sf + 1; composition of scalefactor 2:
* one additional shift of syn values + fMult => fMultDiv2 */
noise_in[i] =
(fMult(gainSGL, syn[i + i_subfr] - (syn[i + i_subfr - T] >> 1) -
(syn[i + i_subfr + T] >> 1))) >>
s1;
scaleValue(fMultDiv2(gainSGL, (syn[i + i_subfr] >> 1) -
(syn[i + i_subfr - T] >> 2) -
(syn[i + i_subfr + T] >> 2)),
2 - s1);
}
for (i = lg; i < L_SUBFR; i++) {
/* scaled with SF_SYNTH + gain_sf + 1 */
/* scaled with SF_SYNTH + gain_sf + 1; composition of scalefactor 2:
* one additional shift of syn values + fMult => fMultDiv2 */
noise_in[i] =
(fMult(gainSGL, syn[i + i_subfr] - syn[i + i_subfr - T])) >> s1;
scaleValue(fMultDiv2(gainSGL, (syn[i + i_subfr] >> 1) -
(syn[i + i_subfr - T] >> 1)),
2 - s1);
}
}
} else {
@ -364,7 +375,7 @@ void bass_pf_1sf_delay(
{
filtLP(&syn[i_subfr - L_SUBFR], &synth_out[i_subfr], noise,
fdk_dec_filt_lp, L_SUBFR, L_FILT);
fdk_dec_filt_lp, aacOutDataHeadroom, L_SUBFR, L_FILT);
}
}
@ -377,9 +388,9 @@ void bass_pf_1sf_delay(
/* Output scaling of the BPF memory */
scaleValues(mem_bpf, (L_FILT + L_SUBFR), -1);
/* Copy the rest of the signal (after the fac) */
scaleValuesSaturate((FIXP_PCM *)&synth_out[l_frame],
(FIXP_DBL *)&syn[l_frame - L_SUBFR],
(frame_length - l_frame), MDCT_OUT_HEADROOM);
scaleValuesSaturate(
(PCM_DEC *)&synth_out[l_frame], (FIXP_DBL *)&syn[l_frame - L_SUBFR],
(frame_length - l_frame), MDCT_OUT_HEADROOM - aacOutDataHeadroom);
}
return;
@ -1222,7 +1233,7 @@ AAC_DECODER_ERROR CLpdChannelStream_Read(
(INT)(samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
(INT)PIT_MIN_12k8;
if ((samplingRate < 6000) || (samplingRate > 24000)) {
if ((samplingRate < FAC_FSCALE_MIN) || (samplingRate > FAC_FSCALE_MAX)) {
error = AAC_DEC_PARSE_ERROR;
goto bail;
}
@ -1546,9 +1557,9 @@ void CLpdChannelStream_Decode(
AAC_DECODER_ERROR CLpd_RenderTimeSignal(
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData,
INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, UINT flags,
UINT strmFlags) {
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC *pTimeData,
INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk,
const INT aacOutDataHeadroom, UINT flags, UINT strmFlags) {
UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
AAC_DECODER_ERROR error = AAC_DEC_OK;
int k, i_offset;
@ -2011,7 +2022,8 @@ AAC_DECODER_ERROR CLpd_RenderTimeSignal(
{
bass_pf_1sf_delay(p2_synth, pitch, pit_gain, lFrame, lFrame / facFB,
mod[nbDiv - 1] ? (SynDelay - (lDiv / 2)) : SynDelay,
pTimeData, pAacDecoderStaticChannelInfo->mem_bpf);
pTimeData, aacOutDataHeadroom,
pAacDecoderStaticChannelInfo->mem_bpf);
}
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -140,13 +140,14 @@ void CLpdChannelStream_Decode(
* \param pTimeData pointer to output buffer
* \param samplesPerFrame amount of output samples
* \param pSamplingRateInfo holds the sampling rate information
* \param pWorkBuffer1 pointer to work buffer for temporal data
* \param aacOutDataHeadroom headroom of the output time signal to prevent
* clipping
*/
AAC_DECODER_ERROR CLpd_RenderTimeSignal(
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData,
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC *pTimeData,
INT samplesPerFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk,
UINT flags, UINT strmFlags);
const INT aacOutDataHeadroom, UINT flags, UINT strmFlags);
static inline INT CLpd_FAC_getLength(int fNotShortBlock, int fac_length_long) {
if (fNotShortBlock) {
@ -156,8 +157,9 @@ static inline INT CLpd_FAC_getLength(int fNotShortBlock, int fac_length_long) {
}
}
void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
const FIXP_SGL *filt, INT stop, int len);
void filtLP(const FIXP_DBL *syn, PCM_DEC *syn_out, FIXP_DBL *noise,
const FIXP_SGL *filt, const INT aacOutDataHeadroom, INT stop,
int len);
/**
* \brief perform a low-frequency pitch enhancement on time domain signal
@ -171,13 +173,14 @@ void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
* \param[in] l_frame length of filtering, must be multiple of L_SUBFR
* \param[in] l_next length of allowed look ahead on syn[i], i < l_frame+l_next
* \param[out] synth_out pointer to time domain output signal
* \param[in] headroom of the output time signal to prevent clipping
* \param[in,out] mem_bpf pointer to filter memory (L_FILT+L_SUBFR)
*/
void bass_pf_1sf_delay(FIXP_DBL syn[], const INT T_sf[], FIXP_DBL *pit_gain,
const int frame_length, const INT l_frame,
const INT l_next, FIXP_PCM *synth_out,
FIXP_DBL mem_bpf[]);
const INT l_next, PCM_DEC *synth_out,
const INT aacOutDataHeadroom, FIXP_DBL mem_bpf[]);
/**
* \brief random sign generator for FD and TCX noise filling

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -149,12 +149,6 @@ All API header files are located in the folder /include of the release package.
All header files are provided for usage in C/C++ programs. The AAC encoder
library API functions are located in aacenc_lib.h.
In binary releases the encoder core resides in statically linkable libraries
called for example libAACenc.a/libFDK.a (LINUX) or FDK_fastaaclib.lib (MS Visual
C++) for the plain AAC-LC core encoder and libSBRenc.a (LINUX) or
FDK_sbrEncLib.lib (MS Visual C++) for the SBR (Spectral Band Replication) and PS
(Parametric Stereo) modules.
\section CallingSequence Calling Sequence
For encoding of ISO/MPEG-2/4 AAC bitstreams the following sequence is mandatory.
@ -326,18 +320,12 @@ input buffer, simulating a modulo buffer: \code if (outargs.numInSamples>0) {
\endcode
\section writeOutData Output Bitstream Data
If any AAC bitstream data is available, write it to output file or device. This
can be done once the following condition is true: \code if
(outargs.numOutBytes>0) {
If any AAC bitstream data is available, write it to output file or device as
follows. \code if (outargs.numOutBytes>0) { FDKfwrite(outputBuffer,
outargs.numOutBytes, 1, pOutFile);
}
\endcode
If you use file I/O then for example call mpegFileWrite_Write() from the library
libMpegFileWrite \code mpegFileWrite_Write(hMpegFile, outputBuffer,
outargs.numOutBytes, aacEncoder_GetParam(hAacEncoder, AACENC_GRANULE_LENGTH));
\endcode
\section cfgMetaData Meta Data Configuration
If the present library is configured with Metadata support, it is possible to
@ -427,7 +415,7 @@ switch (nChannels) {
return chMode;
\endcode
\subsection bitreservoir Bitreservoir Configuration
\subsection peakbitrate Peak Bitrate Configuration
In AAC, the default bitreservoir configuration depends on the chosen bitrate per
frame and the number of effective channels. The size can be determined as below.
\f[
@ -436,17 +424,10 @@ bitreservoir = nEffChannels*6144 - (bitrate*framelength/samplerate)
Due to audio quality concerns it is not recommended to change the bitreservoir
size to a lower value than the default setting! However, for minimizing the
delay for streaming applications or for achieving a constant size of the
bitstream packages in each frame, it may be necessaray to change the
bitreservoir size. This can be done with the ::AACENC_PEAK_BITRATE parameter.
\code
bitstream packages in each frame, it may be necessaray to limit the maximum bits
per frame size. This can be done with the ::AACENC_PEAK_BITRATE parameter. \code
aacEncoder_SetParam(hAacEncoder, AACENC_PEAK_BITRATE, value);
\endcode
By setting ::AACENC_BITRATEMODE to fixed framing, the bitreservoir is disabled.
A disabled bitreservoir results in a constant size for each bitstream package.
Please note that especially at lower bitrates a disabled bitreservoir can
downgrade the audio quality considerably! The default bitreservoir configuration
can be achieved as follows. \code aacEncoder_SetParam(hAacEncoder,
AACENC_BITRESERVOIR, -1); \endcode
To achieve acceptable audio quality with a reduced bitreservoir size setting at
least 1000 bits per audio channel is recommended. For a multichannel audio file
@ -455,31 +436,32 @@ audio quality.
\subsection vbrmode Variable Bitrate Mode
The encoder provides various Variable Bitrate Modes that differ in audio quality
and average overall bitrate. The given values are averages over time, different
encoder settings and strongly depend on the type of audio signal. The VBR
configurations can be adjusted via ::AACENC_BITRATEMODE encoder parameter.
The variable bitrate (VBR) mode coding adapts the bit consumption to the
psychoacoustic requirements of the signal. The encoder ignores the user-defined
bit rate and selects a suitable pre-defined configuration based on the provided
AOT. The VBR mode 1 is tuned for HE-AACv2, for VBR mode 2, HE-AACv1 should be
used. VBR modes 3-5 should be used with Low-Complexity AAC. When encoding
AAC-ELD, the best mode is selected automatically.
The bitrates given in the table are averages over time and different encoder
settings. They strongly depend on the type of audio signal. The VBR
configurations can be adjusted with the ::AACENC_BITRATEMODE encoder parameter.
\verbatim
--------------------------------------------
VBR_MODE | Approx. Bitrate in kbps/channel
| AAC-LC | AAC-LD/AC_ELD
----------+---------------+-----------------
VBR_1 | 32 - 48 | 32 - 56
VBR_2 | 40 - 56 | 40 - 64
VBR_3 | 48 - 64 | 48 - 72
VBR_4 | 64 - 80 | 64 - 88
VBR_5 | 96 - 120 | 112 - 144
-----------------------------------------------
VBR_MODE | Approx. Bitrate in kbps for stereo
| AAC-LC | AAC-ELD
----------+---------------+--------------------
VBR_1 | 32 (HE-AACv2) | 48
VBR_2 | 72 (HE-AACv1) | 56
VBR_3 | 112 | 72
VBR_4 | 148 | 148
VBR_5 | 228 | 224
--------------------------------------------
\endverbatim
The bitrate ranges apply for individual audio channels. In case of multichannel
configurations the average bitrate might be estimated by multiplying with the
number of effective channels. This corresponds to all audio input channels
exclusively the low frequency channel. At configurations which are making use of
downmix modules the AAC core channels respectively downmix channels shall be
considered. For ::AACENC_AOT which are using SBR, the average bitrate can be
estimated by using the ratio of 0.5 for dualrate SBR and 0.75 for downsampled
SBR configurations.
Note that these figures are valid for stereo encoding only. VBR modes 2-5 will
yield much lower bit rates when encoding single-channel input. For
configurations which are making use of downmix modules the AAC core channels
respectively downmix channels shall be considered.
\subsection encQual Audio Quality Considerations
The default encoder configuration is suggested to be used. Encoder tools such as
@ -967,9 +949,7 @@ in this Fraunhofer IIS AAC encoder. AAC has been designed in that way.
\subsection BEHAVIOUR_ESTIM_AVG_FRAMESIZES Estimating Average Frame Sizes
A HE-AAC v1 or v2 audio frame contains 2048 PCM samples per channel (there is
also one mode with 1920 samples per channel but this is only for special
purposes such as DAB+ digital radio).
A HE-AAC v1 or v2 audio frame contains 2048 PCM samples per channel.
The number of HE-AAC frames \f$N\_FRAMES\f$ per second at 44.1 kHz is:
@ -1086,9 +1066,7 @@ typedef struct AACENCODER *HANDLE_AACENCODER;
typedef struct {
UINT maxOutBufBytes; /*!< Maximum number of encoder bitstream bytes within one
frame. Size depends on maximum number of supported
channels in encoder instance. For superframing (as
used for example in DAB+), size has to be a multiple
accordingly. */
channels in encoder instance. */
UINT maxAncBytes; /*!< Maximum number of ancillary data bytes which can be
inserted into bitstream within one frame. */

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -204,5 +204,5 @@ QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel(int n, UCHAR *dynamic_RAM) {
* (dynamic_RAM + P_BUF_0 + n*sizeof(QC_OUT_CHANNEL)) is sufficiently aligned,
* so the cast is safe */
return reinterpret_cast<QC_OUT_CHANNEL *>(reinterpret_cast<void *>(
dynamic_RAM + P_BUF_0 + n * sizeof(QC_OUT_CHANNEL)));
dynamic_RAM + P_BUF_0 + n * ALIGN_SIZE(sizeof(QC_OUT_CHANNEL))));
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -198,7 +198,7 @@ struct AAC_ENC {
+++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
#define BUF_SIZE_0 (ALIGN_SIZE(sizeof(QC_OUT_CHANNEL) * (8)))
#define BUF_SIZE_0 (ALIGN_SIZE(sizeof(QC_OUT_CHANNEL)) * (8))
#define BUF_SIZE_1 \
(ALIGN_SIZE(maxSize(maxSize(sizeof(PSY_DYNAMIC), \
(BIT_LOOK_UP_SIZE + MERGE_GAIN_LOOK_UP_SIZE)), \

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -114,6 +114,8 @@ amm-info@iis.fraunhofer.de
#include "genericStds.h"
#define BITRES_MIN \
300 /* default threshold for using reduced/disabled bitres mode */
#define BITRES_MAX_LD 4000
#define BITRES_MIN_LD 500
#define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */
@ -550,7 +552,8 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(
(config->minBitsPerFrame != -1) ? config->minBitsPerFrame : 0;
qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7);
} else {
INT bitreservoir = -1; /* default bitrservoir size*/
INT bitreservoir = -1; /* default bitreservoir size*/
bitresMin = BITRES_MIN;
if (isLowDelay(config->audioObjectType)) {
INT brPerChannel = config->bitRate / config->nChannels;
brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
@ -601,9 +604,9 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(
qcInit.nSubFrames = config->nSubFrames;
qcInit.padding.paddingRest = config->sampleRate;
if (qcInit.bitRes >= bitresMin * config->nChannels) {
if (qcInit.maxBits - qcInit.averageBits >= bitresMin * config->nChannels) {
qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
} else if (qcInit.bitRes > 0) {
} else if (qcInit.maxBits > qcInit.averageBits) {
qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */
} else {
qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */

View File

@ -110,9 +110,9 @@ amm-info@iis.fraunhofer.de
/* Encoder library info */
#define AACENCODER_LIB_VL0 4
#define AACENCODER_LIB_VL1 0
#define AACENCODER_LIB_VL2 0
#define AACENCODER_LIB_VL2 1
#define AACENCODER_LIB_TITLE "AAC Encoder"
#ifdef __ANDROID__
#ifdef SUPPRESS_BUILD_DATE_INFO
#define AACENCODER_LIB_BUILD_DATE ""
#define AACENCODER_LIB_BUILD_TIME ""
#else
@ -446,6 +446,24 @@ static SBR_PS_SIGNALING getSbrSignalingMode(
return sbrSignaling;
}
static inline INT getAssociatedChElement(SBR_ELEMENT_INFO *elInfoSbr,
CHANNEL_MAPPING *channelMapping) {
ELEMENT_INFO *elInfo = channelMapping->elInfo;
INT nElements = channelMapping->nElements;
INT associatedChElement = -1;
int i;
for (i = 0; i < nElements; i++) {
if (elInfoSbr->elType == elInfo[i].elType &&
elInfoSbr->instanceTag == elInfo[i].instanceTag) {
associatedChElement = i;
break;
}
}
return associatedChElement;
}
/****************************************************************************
Allocate Encoder
****************************************************************************/
@ -1921,7 +1939,15 @@ AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
{
hAacEncoder->extPayload[nExtensions].dataSize =
hAacEncoder->pSbrPayload->dataSize[nPayload][i];
hAacEncoder->extPayload[nExtensions].associatedChElement = i;
hAacEncoder->extPayload[nExtensions].associatedChElement =
getAssociatedChElement(
&hAacEncoder->hEnvEnc->sbrElement[i]->elInfo,
&hAacEncoder->hAacEnc->channelMapping);
if (hAacEncoder->extPayload[nExtensions].associatedChElement ==
-1) {
err = AACENC_ENCODE_ERROR;
goto bail;
}
}
hAacEncoder->extPayload[nExtensions].dataType =
EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set

View File

@ -1302,14 +1302,6 @@ static void FDKaacEnc_reduceThresholdsVBR(
if (sfbThrReducedLdData < FL2FXCONST_DBL(-0.5f))
sfbThrReducedLdData = FL2FXCONST_DBL(-1.f);
/* minimum of 29 dB Ratio for Thresholds */
if ((sfbEnLdData + FL2FXCONST_DBL(1.0f)) >
FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)) {
sfbThrReducedLdData = fixMax(
sfbThrReducedLdData,
sfbEnLdData - FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING));
}
sfbThrReducedLdData = fixMax(MIN_LDTHRESH, sfbThrReducedLdData);
qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -151,11 +151,11 @@ typedef struct {
static const BANDWIDTH_TAB_VBR bandWidthTableVBR[] = {
{AACENC_BR_MODE_CBR, 0, 0},
{AACENC_BR_MODE_VBR_1, 13050, 13050},
{AACENC_BR_MODE_VBR_2, 13050, 13050},
{AACENC_BR_MODE_VBR_3, 14260, 14260},
{AACENC_BR_MODE_VBR_4, 15500, 15500},
{AACENC_BR_MODE_VBR_5, 48000, 48000},
{AACENC_BR_MODE_VBR_1, 13000, 13000},
{AACENC_BR_MODE_VBR_2, 13000, 13000},
{AACENC_BR_MODE_VBR_3, 15750, 15750},
{AACENC_BR_MODE_VBR_4, 16500, 16500},
{AACENC_BR_MODE_VBR_5, 19293, 19293},
{AACENC_BR_MODE_SFR, 0, 0},
{AACENC_BR_MODE_FF, 0, 0}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -121,20 +121,15 @@ typedef struct {
static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = {
{QCDATA_BR_MODE_VBR_1,
FL2FXCONST_DBL(0.160f)}, /* Approx. 32 - 48 (AC-LC), 32 - 56
(AAC-LD/ELD) kbps/channel */
FL2FXCONST_DBL(0.150f)}, /* Approx. 32 kbps mono AAC-LC + SBR + PS */
{QCDATA_BR_MODE_VBR_2,
FL2FXCONST_DBL(0.148f)}, /* Approx. 40 - 56 (AC-LC), 40 - 64
(AAC-LD/ELD) kbps/channel */
FL2FXCONST_DBL(0.162f)}, /* Approx. 64 kbps stereo AAC-LC + SBR */
{QCDATA_BR_MODE_VBR_3,
FL2FXCONST_DBL(0.135f)}, /* Approx. 48 - 64 (AC-LC), 48 - 72
(AAC-LD/ELD) kbps/channel */
FL2FXCONST_DBL(0.176f)}, /* Approx. 96 kbps stereo AAC-LC */
{QCDATA_BR_MODE_VBR_4,
FL2FXCONST_DBL(0.111f)}, /* Approx. 64 - 80 (AC-LC), 64 - 88
(AAC-LD/ELD) kbps/channel */
FL2FXCONST_DBL(0.120f)}, /* Approx. 128 kbps stereo AAC-LC */
{QCDATA_BR_MODE_VBR_5,
FL2FXCONST_DBL(0.070f)} /* Approx. 96 - 120 (AC-LC), 112 - 144
(AAC-LD/ELD) kbps/channel */
FL2FXCONST_DBL(0.070f)} /* Approx. 192 kbps stereo AAC-LC */
};
static INT isConstantBitrateMode(const QCDATA_BR_MODE bitrateMode) {

View File

@ -114,6 +114,8 @@ amm-info@iis.fraunhofer.de
extern "C" {
#endif
#define DRC_DEC_LOUDNESS_NOT_PRESENT (LONG)0x7FFFFFFE
typedef struct s_drc_decoder* HANDLE_DRC_DECODER;
typedef struct s_uni_drc_interface* HANDLE_UNI_DRC_INTERFACE;
typedef struct s_selection_process_output* HANDLE_SEL_PROC_OUTPUT;
@ -150,9 +152,12 @@ typedef enum {
DRC_DEC_IS_ACTIVE, /**< MPEG-D DRC payload is present and at least one of
Dynamic Range Control (DRC) or Loudness Normalization
(LN) is activated */
DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED /**< number of output channels if
appropriate downmixInstruction exists
*/
DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED, /**< number of output channels if
appropriate downmixInstruction
exists */
DRC_DEC_OUTPUT_LOUDNESS /**< output loudness in dB, with exponent e = 7, or
DRC_DEC_LOUDNESS_NOT_PRESENT if no loudness is
contained in the bitstream */
} DRC_DEC_USERPARAM;
typedef enum {

View File

@ -112,7 +112,7 @@ amm-info@iis.fraunhofer.de
#define DRCDEC_LIB_VL1 1
#define DRCDEC_LIB_VL2 0
#define DRCDEC_LIB_TITLE "MPEG-D DRC Decoder Lib"
#ifdef __ANDROID__
#ifdef SUPPRESS_BUILD_DATE_INFO
#define DRCDEC_LIB_BUILD_DATE ""
#define DRCDEC_LIB_BUILD_TIME ""
#else
@ -145,6 +145,10 @@ struct s_drc_decoder {
SEL_PROC_OUTPUT selProcOutput;
} DRC_DECODER;
static int _getGainStatus(HANDLE_UNI_DRC_GAIN hUniDrcGain) {
return hUniDrcGain->status;
}
static int isResetNeeded(HANDLE_DRC_DECODER hDrcDec,
const SEL_PROC_OUTPUT oldSelProcOutput) {
int i, resetNeeded = 0;
@ -515,6 +519,8 @@ LONG FDK_drcDec_GetParam(HANDLE_DRC_DECODER hDrcDec,
}
case DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED:
return (LONG)hDrcDec->selProcOutput.targetChannelCount;
case DRC_DEC_OUTPUT_LOUDNESS:
return (LONG)hDrcDec->selProcOutput.outputLoudness;
default:
return 0;
}
@ -729,7 +735,9 @@ FDK_drcDec_ReadUniDrcGain(HANDLE_DRC_DECODER hDrcDec,
&(hDrcDec->uniDrcGain));
if (dErr) return DRC_DEC_NOT_OK;
hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
if (_getGainStatus(&(hDrcDec->uniDrcGain))) {
hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
}
return DRC_DEC_OK;
}
@ -751,7 +759,9 @@ FDK_drcDec_ReadUniDrc(HANDLE_DRC_DECODER hDrcDec,
startSelectionProcess(hDrcDec);
if (dErr) return DRC_DEC_NOT_OK;
hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
if (_getGainStatus(&(hDrcDec->uniDrcGain))) {
hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
}
return DRC_DEC_OK;
}

View File

@ -297,9 +297,11 @@ drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec,
int seq, gainSequenceCount;
DRC_COEFFICIENTS_UNI_DRC* pCoef =
selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
if (pCoef == NULL) return DE_OK;
gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
if (pCoef && pCoef->gainSequenceCount) {
gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
} else {
gainSequenceCount = 1;
}
for (seq = 0; seq < gainSequenceCount; seq++) {
int lastNodeIndex = 0;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -199,11 +199,8 @@ drcDec_readUniDrc(HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
}
}
if (hUniDrcGain != NULL) {
err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault,
hUniDrcGain);
if (err) return err;
}
err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault,
hUniDrcGain);
return err;
}
@ -487,10 +484,13 @@ drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
int seq, gainSequenceCount;
DRC_COEFFICIENTS_UNI_DRC* pCoef =
selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
if (pCoef == NULL) return DE_OK;
if (hUniDrcGain == NULL) return DE_OK; /* hUniDrcGain not initialized yet */
gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
if (hUniDrcGain == NULL) return DE_NOT_OK;
hUniDrcGain->status = 0;
if (pCoef) {
gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
} else {
gainSequenceCount = 0;
}
for (seq = 0; seq < gainSequenceCount; seq++) {
UCHAR index = pCoef->gainSetIndexForGainSequence[seq];
@ -518,6 +518,9 @@ drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
if (err) return err;
}
if (err == DE_OK && gainSequenceCount > 0) {
hUniDrcGain->status = 1;
}
return err;
}
@ -1018,6 +1021,7 @@ static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
int additionalDrcSetIdPresent, additionalDrcSetIdCount;
int dependsOnEqSetPresent, eqChannelGroupCount, tdFilterCascadePresent,
subbandGainsPresent, eqTransitionDurationPresent;
UCHAR eqChannelGroupForChannel[8];
FDKpushFor(hBs, 6); /* eqSetId */
FDKpushFor(hBs, 4); /* eqSetComplexityLevel */
@ -1067,7 +1071,6 @@ static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
eqChannelGroupCount = 0;
for (c = 0; c < channelCount; c++) {
UCHAR eqChannelGroupForChannel[8];
int newGroup = 1;
if (c >= 8) return DE_MEMORY_ERROR;
eqChannelGroupForChannel[c] = FDKreadBits(hBs, 7);

View File

@ -103,8 +103,6 @@ amm-info@iis.fraunhofer.de
#include "drcDec_selectionProcess.h"
#include "drcDec_tools.h"
#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL) MAXVAL_DBL
typedef enum {
DETR_NONE = 0,
DETR_NIGHT = 1,
@ -753,8 +751,8 @@ static DRCDEC_SELECTION_PROCESS_RETURN _initDefaultParams(
hSelProcInput->loudnessNormalizationOn = 1;
hSelProcInput->targetLoudness = FL2FXCONST_DBL(-24.0f / (float)(1 << 7));
hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
hSelProcInput->loudnessMeasurementMethod = MDR_DEFAULT;
hSelProcInput->loudnessMeasurementSystem = MSR_DEFAULT;
hSelProcInput->loudnessMeasurementMethod = MDR_ANCHOR_LOUDNESS;
hSelProcInput->loudnessMeasurementSystem = MSR_EXPERT_PANEL;
hSelProcInput->loudnessMeasurementPreProc = LPR_DEFAULT;
hSelProcInput->deviceCutOffFrequency = 500;
hSelProcInput->loudnessNormalizationGainDbMax =
@ -956,17 +954,31 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement4(
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}
/* #5: The number of DRC bands is supported. */
/* #5: The number of DRC bands is supported. Moreover, gainSetIndex and
* gainSequenceIndex are within the allowed range. */
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5(
DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
DRC_COEFFICIENTS_UNI_DRC* pCoef, int* pMatchFound) {
int i;
int b, i;
*pMatchFound = 1;
if (pDrcInstructionUniDrc->drcSetId < 0) /* virtual DRC sets are okay */
{
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}
if (pCoef == NULL) /* check for parametricDRC */
{
*pMatchFound = 1;
*pMatchFound = 0; /* parametricDRC not supported */
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}
if (pCoef->drcLocation !=
pDrcInstructionUniDrc
->drcLocation) /* drcLocation must be LOCATION_SELECTED */
{
*pMatchFound = 0;
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}
@ -974,10 +986,14 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5(
int indexDrcCoeff = pDrcInstructionUniDrc->gainSetIndexForChannelGroup[i];
int bandCount = 0;
if (indexDrcCoeff >= 12) {
*pMatchFound = 0;
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}
if (indexDrcCoeff > pCoef->gainSetCount - 1) /* check for parametricDRC */
{
*pMatchFound = 1;
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
continue;
}
GAIN_SET* gainSet = &(pCoef->gainSet[indexDrcCoeff]);
@ -986,6 +1002,14 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5(
if (bandCount > 4) {
*pMatchFound = 0;
}
for (b = 0; b < bandCount; b++) {
if ((gainSet->gainSequenceIndex[b] >= 12) ||
(gainSet->gainSequenceIndex[b] >= pCoef->gainSequenceCount)) {
*pMatchFound = 0;
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}
}
}
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
@ -1078,6 +1102,19 @@ static int _targetLoudnessInRange(
return retVal;
}
static int _drcSetIsUsable(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
DRC_INSTRUCTIONS_UNI_DRC* pInst) {
int usable = 0;
DRC_COEFFICIENTS_UNI_DRC* pCoef =
selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
/* check if ID is unique */
if (selectDrcInstructions(hUniDrcConfig, pInst->drcSetId) != pInst) return 0;
/* sanity check on drcInstructions */
_preSelectionRequirement5(pInst, pCoef, &usable);
return usable;
}
/* #8: The range of the target loudness specified for a DRC set has to include
* the requested decoder target loudness. */
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
@ -1097,9 +1134,8 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
FIXP_DBL loudnessDeviationMax =
((FIXP_DBL)hSelProcInput->loudnessDeviationMax) << (DFRACT_BITS - 1 - 7);
;
if (hSelProcInput->loudnessNormalizationOn) {
{
retVal = _getLoudness(hLoudnessInfoSet, hSelProcInput->albumMode,
hSelProcInput->loudnessMeasurementMethod,
hSelProcInput->loudnessMeasurementSystem,
@ -1108,9 +1144,10 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
hSelProcInput->downmixIdRequested[downmixIdIndex],
&loudnessNormalizationGainDb, &loudness);
if (retVal) return (retVal);
} else {
}
if (!hSelProcInput->loudnessNormalizationOn) {
loudnessNormalizationGainDb = (FIXP_DBL)0;
loudness = UNDEFINED_LOUDNESS_VALUE;
}
retVal = _getSignalPeakLevel(
@ -2031,6 +2068,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
pSelectionData->loudnessNormalizationGainDbAdjusted +
hSelProcInput->loudnessNormalizationGainModificationDb;
hSelProcOutput->outputPeakLevelDb = pSelectionData->outputPeakLevel;
hSelProcOutput->outputLoudness = pSelectionData->outputLoudness;
hSelProcOutput->boost = boost;
hSelProcOutput->compress = compress;
@ -2051,8 +2089,11 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
int dependsOnDrcSetID = pSelectionData->pInst->dependsOnDrcSet;
for (i = 0; i < hUniDrcConfig->drcInstructionsCountInclVirtual; i++) {
if (hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId ==
dependsOnDrcSetID) {
DRC_INSTRUCTIONS_UNI_DRC* pInst =
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
if (pInst->drcSetId == dependsOnDrcSetID) {
hSelProcOutput->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
hSelProcOutput->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] =
@ -2071,6 +2112,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
DRC_INSTRUCTIONS_UNI_DRC* pInst =
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
if (pInst->drcSetEffect & EB_FADE) {
if (pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) {
@ -2098,6 +2140,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
DRC_INSTRUCTIONS_UNI_DRC* pInst =
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
for (j = 0; j < pInst->downmixIdCount; j++) {
@ -2124,6 +2167,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
DRC_INSTRUCTIONS_UNI_DRC* pInst =
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
for (j = 0; j < pInst->downmixIdCount; j++) {
@ -2231,6 +2275,11 @@ static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelection(
for (j = 0; j < hUniDrcConfig->drcInstructionsCountInclVirtual; j++) {
DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction =
&(hUniDrcConfig->drcInstructionsUniDrc[j]);
/* check if ID is unique */
if (selectDrcInstructions(hUniDrcConfig, pDrcInstruction->drcSetId) !=
pDrcInstruction)
continue;
retVal = _drcSetPreSelectionSingleInstruction(
hSelProcInput, i, hUniDrcConfig, hLoudnessInfoSet, pDrcInstruction,
*ppCandidatesPotential, *ppCandidatesSelected, codecMode);

View File

@ -111,6 +111,8 @@ amm-info@iis.fraunhofer.de
typedef struct s_drcdec_selection_process* HANDLE_DRC_SELECTION_PROCESS;
#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL)(MAXVAL_DBL - 1)
typedef enum {
DRCDEC_SELECTION_PROCESS_NO_ERROR = 0,

View File

@ -130,6 +130,9 @@ typedef struct {
UCHAR uniDrcGainExtPresent;
UNI_DRC_GAIN_EXTENSION uniDrcGainExtension;
/* derived data */
UCHAR status;
} UNI_DRC_GAIN, *HANDLE_UNI_DRC_GAIN;
/****************/

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -285,6 +285,9 @@ static DRC_ERROR _compressorIO_sigmoid_common(
&e_tmp2);
invExp = fDivNorm(FL2FXCONST_DBL(1.0f / (float)(1 << 1)), exp, &e_invExp);
e_invExp += 1 - 5;
if (tmp2 < (FIXP_DBL)0) {
return DE_NOT_OK;
}
denom = fPow(tmp2, e_tmp2, invExp, e_invExp, &e_denom);
*out = fDivNormSigned(tmp, denom, &e_out);
e_out += 7 - e_denom;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -123,11 +123,10 @@ typedef enum {
#define QMF_WB_SECTION_SIZE (1024 * 2)
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL)
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL)
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL)
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL)
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL)
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL)
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL)
#define QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS (64)
#define QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS (QMF_MAX_SYNTHESIS_BANDS)
@ -145,15 +144,15 @@ H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL)
#define QMF_DOMAIN_OV_TIMESLOTS_16 (3)
#define QMF_DOMAIN_OV_TIMESLOTS_32 (6)
H_ALLOC_MEM(AnaQmfStates, FIXP_QAS)
H_ALLOC_MEM(AnaQmfStates, FIXP_DBL)
H_ALLOC_MEM(SynQmfStates, FIXP_QSS)
H_ALLOC_MEM(QmfSlotsReal, FIXP_DBL *)
H_ALLOC_MEM(QmfSlotsImag, FIXP_DBL *)
H_ALLOC_MEM(QmfOverlapBuffer, FIXP_DBL)
H_ALLOC_MEM(AnaQmfStates16, FIXP_QAS)
H_ALLOC_MEM(AnaQmfStates24, FIXP_QAS)
H_ALLOC_MEM(AnaQmfStates32, FIXP_QAS)
H_ALLOC_MEM(AnaQmfStates16, FIXP_DBL)
H_ALLOC_MEM(AnaQmfStates24, FIXP_DBL)
H_ALLOC_MEM(AnaQmfStates32, FIXP_DBL)
H_ALLOC_MEM(QmfSlotsReal16, FIXP_DBL *)
H_ALLOC_MEM(QmfSlotsReal32, FIXP_DBL *)
H_ALLOC_MEM(QmfSlotsImag16, FIXP_DBL *)
@ -161,8 +160,6 @@ H_ALLOC_MEM(QmfSlotsImag32, FIXP_DBL *)
H_ALLOC_MEM(QmfOverlapBuffer16, FIXP_DBL)
H_ALLOC_MEM(QmfOverlapBuffer32, FIXP_DBL)
#define QDOM_PCM INT_PCM
/**
* Structure to hold the configuration data which is global whithin a QMF domain
* instance.
@ -182,9 +179,6 @@ typedef struct {
park a channel if only one processing channel is
available. */
UCHAR parkChannel_requested;
QDOM_PCM
*TDinput; /*!< Pointer to time domain data used as input for the QMF
analysis. */
FIXP_DBL *
pWorkBuffer[QMF_MAX_WB_SECTIONS]; /*!< Pointerarray to volatile memory. */
UINT flags; /*!< Flags to be set on all QMF analysis/synthesis filter
@ -244,7 +238,7 @@ typedef struct {
(workBuf_nTimeSlots * workBuf_nBands * CMPLX_MOD). */
USHORT workBufferOffset; /*!< Offset within work buffer. */
USHORT workBufferSectSize; /*!< Size of work buffer section. */
FIXP_QAS *
FIXP_DBL *
pAnaQmfStates; /*!< Pointer to QMF analysis states (persistent memory). */
FIXP_DBL
*pOverlapBuffer; /*!< Pointer to QMF overlap/delay memory (persistent

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -171,6 +171,19 @@ extern const FIXP_DBL invSqrtTab[SQRT_VALUES];
* \return non-zero if (a_m*2^a_e) < (b_m*2^b_e), 0 otherwise
*/
FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e) {
INT n;
n = fixnorm_D(a_m);
a_m <<= n;
a_e -= n;
n = fixnorm_D(b_m);
b_m <<= n;
b_e -= n;
if (a_m == (FIXP_DBL)0) a_e = b_e;
if (b_m == (FIXP_DBL)0) b_e = a_e;
if (a_e > b_e) {
return ((b_m >> fMin(a_e - b_e, DFRACT_BITS - 1)) > a_m);
} else {
@ -179,6 +192,19 @@ FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e) {
}
FDK_INLINE INT fIsLessThan(FIXP_SGL a_m, INT a_e, FIXP_SGL b_m, INT b_e) {
INT n;
n = fixnorm_S(a_m);
a_m <<= n;
a_e -= n;
n = fixnorm_S(b_m);
b_m <<= n;
b_e -= n;
if (a_m == (FIXP_SGL)0) a_e = b_e;
if (b_m == (FIXP_SGL)0) b_e = a_e;
if (a_e > b_e) {
return ((b_m >> fMin(a_e - b_e, FRACT_BITS - 1)) > a_m);
} else {
@ -545,15 +571,20 @@ inline INT fMultIceil(FIXP_DBL a, INT b) {
m = fMultNorm(a, (FIXP_DBL)b, &m_e);
if (m_e < (INT)0) {
if (m_e > (INT)-DFRACT_BITS) {
if (m_e > (INT) - (DFRACT_BITS - 1)) {
mi = (m >> (-m_e));
if ((LONG)m & ((1 << (-m_e)) - 1)) {
mi = mi + (FIXP_DBL)1;
}
} else {
mi = (FIXP_DBL)1;
if (m < (FIXP_DBL)0) {
mi = (FIXP_DBL)0;
if (m > (FIXP_DBL)0) {
mi = (FIXP_DBL)1;
} else {
if ((m_e == -(DFRACT_BITS - 1)) && (m == (FIXP_DBL)MINVAL_DBL)) {
mi = (FIXP_DBL)-1;
} else {
mi = (FIXP_DBL)0;
}
}
}
} else {
@ -744,7 +775,7 @@ FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
/**
* \brief return (base_m * 2^base_e) ^ N
* \param base_m mantissa of the base
* \param base_m mantissa of the base. Must not be negative.
* \param base_e exponent of the base
* \param N power to be calculated of the base
* \param result_e pointer to a INT where the exponent of the result will be

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -106,18 +106,16 @@ amm-info@iis.fraunhofer.de
#include "common_fix.h"
#define MDCT_OUT_HEADROOM 2 /* Output additional headroom */
#define PCM_OUT_BITS SAMPLE_BITS
#define PCM_OUT_BITS DFRACT_BITS
#define PCM_OUT_HEADROOM 8 /* Must have the same values as DMXH_HEADROOM */
#define MDCT_OUTPUT_SCALE (-MDCT_OUT_HEADROOM + (DFRACT_BITS - SAMPLE_BITS))
#define MDCT_OUTPUT_SCALE (-MDCT_OUT_HEADROOM + (DFRACT_BITS - PCM_OUT_BITS))
/* Refer to "Output word length" in ISO/IEC 14496-3:2008(E) 23.2.3.6 */
#define MDCT_OUTPUT_GAIN 16
#if (MDCT_OUTPUT_SCALE >= 0)
#define IMDCT_SCALE(x) SATURATE_RIGHT_SHIFT(x, MDCT_OUTPUT_SCALE, PCM_OUT_BITS)
#else
#define IMDCT_SCALE(x) SATURATE_LEFT_SHIFT(x, -MDCT_OUTPUT_SCALE, PCM_OUT_BITS)
#endif
#define IMDCT_SCALE(x, s) \
SATURATE_RIGHT_SHIFT((x), ((s) + MDCT_OUTPUT_SCALE), PCM_OUT_BITS)
#define IMDCT_SCALE_DBL(x) (FIXP_DBL)(x)
#define IMDCT_SCALE_DBL_LSH1(x) SATURATE_LEFT_SHIFT_ALT((x), 1, DFRACT_BITS)

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -116,6 +116,7 @@ amm-info@iis.fraunhofer.de
#define FIXP_QAS FIXP_PCM
#define QAS_BITS SAMPLE_BITS
#define INT_PCM_QMFIN INT_PCM
#define FIXP_QSS FIXP_DBL
#define QSS_BITS DFRACT_BITS
@ -201,16 +202,25 @@ struct QMF_FILTER_BANK {
typedef struct QMF_FILTER_BANK *HANDLE_QMF_FILTER_BANK;
void qmfAnalysisFiltering(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
const LONG *timeIn, /*!< Time signal */
const int timeIn_e, /*!< Exponent of audio data */
const int stride, /*!< Stride factor of audio data */
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
);
int qmfInitAnalysisFilterBank(
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */
int noCols, /*!< Number of time slots */
int lsb, /*!< Number of lower bands */
int usb, /*!< Number of upper bands */
int no_channels, /*!< Number of critically sampled bands */
int flags); /*!< Flags */
#if SAMPLE_BITS == 16
int qmfInitAnalysisFilterBank(
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
FIXP_DBL *pFilterStates, /*!< Pointer to filter state buffer */
int noCols, /*!< Number of time slots */
int lsb, /*!< Number of lower bands */
int usb, /*!< Number of upper bands */
int no_channels, /*!< Number of critically sampled bands */
int flags); /*!< Flags */
#endif
void qmfAnalysisFiltering(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
@ -222,6 +232,48 @@ void qmfAnalysisFiltering(
const int stride, /*!< Stride factor of audio data */
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
);
#if SAMPLE_BITS == 16
void qmfAnalysisFiltering(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
const LONG *timeIn, /*!< Time signal */
const int timeIn_e, /*!< Exponent of audio data */
const int stride, /*!< Stride factor of audio data */
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
);
#endif
void qmfAnalysisFilteringSlot(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
FIXP_DBL *qmfReal, /*!< Low and High band, real */
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
const INT_PCM *timeIn, /*!< Pointer to input */
const int stride, /*!< stride factor of input */
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
);
#if SAMPLE_BITS == 16
void qmfAnalysisFilteringSlot(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
FIXP_DBL *qmfReal, /*!< Low and High band, real */
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
const LONG *timeIn, /*!< Pointer to input */
const int stride, /*!< stride factor of input */
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
);
#endif
int qmfInitSynthesisFilterBank(
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
FIXP_QSS *pFilterStates, /*!< Pointer to filter state buffer */
int noCols, /*!< Number of time slots */
int lsb, /*!< Number of lower bands */
int usb, /*!< Number of upper bands */
int no_channels, /*!< Number of critically sampled bands */
int flags); /*!< Flags */
void qmfSynthesisFiltering(
HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
@ -234,41 +286,19 @@ void qmfSynthesisFiltering(
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer. It must be
aligned */
);
#if SAMPLE_BITS == 16
int qmfInitAnalysisFilterBank(
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */
int noCols, /*!< Number of time slots */
int lsb, /*!< Number of lower bands */
int usb, /*!< Number of upper bands */
int no_channels, /*!< Number of critically sampled bands */
int flags); /*!< Flags */
void qmfAnalysisFilteringSlot(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
FIXP_DBL *qmfReal, /*!< Low and High band, real */
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
const LONG *timeIn, /*!< Pointer to input */
const int stride, /*!< stride factor of input */
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
void qmfSynthesisFiltering(
HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
FIXP_DBL **QmfBufferReal, /*!< Pointer to real subband slots */
FIXP_DBL **QmfBufferImag, /*!< Pointer to imag subband slots */
const QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
const int ov_len, /*!< Length of band overlap */
LONG *timeOut, /*!< Time signal */
const int timeOut_e, /*!< Target exponent for timeOut */
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
);
void qmfAnalysisFilteringSlot(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
FIXP_DBL *qmfReal, /*!< Low and High band, real */
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
const INT_PCM *timeIn, /*!< Pointer to input */
const int stride, /*!< stride factor of input */
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
);
int qmfInitSynthesisFilterBank(
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
FIXP_QSS *pFilterStates, /*!< Pointer to filter state buffer */
int noCols, /*!< Number of time slots */
int lsb, /*!< Number of lower bands */
int usb, /*!< Number of upper bands */
int no_channels, /*!< Number of critically sampled bands */
int flags); /*!< Flags */
#endif
void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
const FIXP_DBL *realSlot,
@ -276,6 +306,15 @@ void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
const int scaleFactorLowBand,
const int scaleFactorHighBand, INT_PCM *timeOut,
const int timeOut_e, FIXP_DBL *pWorkBuffer);
#if SAMPLE_BITS == 16
void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
const FIXP_DBL *realSlot,
const FIXP_DBL *imagSlot,
const int scaleFactorLowBand,
const int scaleFactorHighBand, LONG *timeOut,
const int timeOut_e, FIXP_DBL *pWorkBuffer);
#endif
void qmfChangeOutScalefactor(
HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
@ -291,11 +330,5 @@ void qmfChangeOutGain(
FIXP_DBL outputGain, /*!< New gain for output data (mantissa) */
int outputGainScale /*!< New gain for output data (exponent) */
);
void qmfSynPrototypeFirSlot(
HANDLE_QMF_FILTER_BANK qmf,
FIXP_DBL *RESTRICT realSlot, /*!< Input: Pointer to real Slot */
FIXP_DBL *RESTRICT imagSlot, /*!< Input: Pointer to imag Slot */
INT_PCM *RESTRICT timeOut, /*!< Time domain data */
const int timeOut_e);
#endif /*ifndef QMF_H */

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -402,4 +402,220 @@ void qmfSynthesisFiltering(
timeOut + (i * L * stride), stride, pWorkBuffer);
} /* no_col loop i */
}
/*!
*
* \brief Create QMF filter bank instance
*
*
* \return 0 if successful
*
*/
int qmfInitAnalysisFilterBank(
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */
FIXP_QAS *pFilterStates, /*!< Handle to filter states */
int noCols, /*!< Number of timeslots per frame */
int lsb, /*!< lower end of QMF */
int usb, /*!< upper end of QMF */
int no_channels, /*!< Number of channels (bands) */
int flags) /*!< Low Power flag */
{
int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb,
no_channels, flags, 0);
if (!(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL)) {
FDKmemclear(h_Qmf->FilterStates,
(2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QAS));
}
FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb);
return err;
}
#ifndef FUNCTION_qmfAnaPrototypeFirSlot
/*!
\brief Perform Analysis Prototype Filtering on a single slot of input data.
*/
static void qmfAnaPrototypeFirSlot(
FIXP_DBL *analysisBuffer,
INT no_channels, /*!< Number channels of analysis filter */
const FIXP_PFT *p_filter, INT p_stride, /*!< Stride of analysis filter */
FIXP_QAS *RESTRICT pFilterStates) {
INT k;
FIXP_DBL accu;
const FIXP_PFT *RESTRICT p_flt = p_filter;
FIXP_DBL *RESTRICT pData_0 = analysisBuffer + 2 * no_channels - 1;
FIXP_DBL *RESTRICT pData_1 = analysisBuffer;
FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates;
FIXP_QAS *RESTRICT sta_1 =
(FIXP_QAS *)pFilterStates + (2 * QMF_NO_POLY * no_channels) - 1;
INT pfltStep = QMF_NO_POLY * (p_stride);
INT staStep1 = no_channels << 1;
INT staStep2 = (no_channels << 3) - 1; /* Rewind one less */
/* FIR filters 127..64 0..63 */
for (k = 0; k < no_channels; k++) {
accu = fMultDiv2(p_flt[0], *sta_1);
sta_1 -= staStep1;
accu += fMultDiv2(p_flt[1], *sta_1);
sta_1 -= staStep1;
accu += fMultDiv2(p_flt[2], *sta_1);
sta_1 -= staStep1;
accu += fMultDiv2(p_flt[3], *sta_1);
sta_1 -= staStep1;
accu += fMultDiv2(p_flt[4], *sta_1);
*pData_1++ = (accu << 1);
sta_1 += staStep2;
p_flt += pfltStep;
accu = fMultDiv2(p_flt[0], *sta_0);
sta_0 += staStep1;
accu += fMultDiv2(p_flt[1], *sta_0);
sta_0 += staStep1;
accu += fMultDiv2(p_flt[2], *sta_0);
sta_0 += staStep1;
accu += fMultDiv2(p_flt[3], *sta_0);
sta_0 += staStep1;
accu += fMultDiv2(p_flt[4], *sta_0);
*pData_0-- = (accu << 1);
sta_0 -= staStep2;
}
}
#endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */
#ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric
/*!
\brief Perform Analysis Prototype Filtering on a single slot of input data.
*/
static void qmfAnaPrototypeFirSlot_NonSymmetric(
FIXP_DBL *analysisBuffer,
int no_channels, /*!< Number channels of analysis filter */
const FIXP_PFT *p_filter, int p_stride, /*!< Stride of analysis filter */
FIXP_QAS *RESTRICT pFilterStates) {
const FIXP_PFT *RESTRICT p_flt = p_filter;
int p, k;
for (k = 0; k < 2 * no_channels; k++) {
FIXP_DBL accu = (FIXP_DBL)0;
p_flt += QMF_NO_POLY * (p_stride - 1);
/*
Perform FIR-Filter
*/
for (p = 0; p < QMF_NO_POLY; p++) {
accu += fMultDiv2(*p_flt++, pFilterStates[2 * no_channels * p]);
}
analysisBuffer[2 * no_channels - 1 - k] = (accu << 1);
pFilterStates++;
}
}
#endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */
/*
* \brief Perform one QMF slot analysis of the time domain data of timeIn
* with specified stride and stores the real part of the subband
* samples in rSubband, and the imaginary part in iSubband
*
* Note: anaQmf->lsb can be greater than anaQmf->no_channels in case
* of implicit resampling (USAC with reduced 3/4 core frame length).
*/
void qmfAnalysisFilteringSlot(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
FIXP_DBL *qmfReal, /*!< Low and High band, real */
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
const INT_PCM_QMFIN *RESTRICT timeIn, /*!< Pointer to input */
const int stride, /*!< stride factor of input */
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
) {
int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1);
/*
Feed time signal into oldest anaQmf->no_channels states
*/
{
FIXP_QAS *FilterStatesAnaTmp = ((FIXP_QAS *)anaQmf->FilterStates) + offset;
/* Feed and scale actual time in slot */
for (int i = anaQmf->no_channels >> 1; i != 0; i--) {
/* Place INT_PCM value left aligned in scaledTimeIn */
*FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
timeIn += stride;
*FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
timeIn += stride;
}
}
if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels,
anaQmf->p_filter, anaQmf->p_stride,
(FIXP_QAS *)anaQmf->FilterStates);
} else {
qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter,
anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates);
}
if (anaQmf->flags & QMF_FLAG_LP) {
if (anaQmf->flags & QMF_FLAG_CLDFB)
qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal);
else
qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal);
} else {
qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag);
}
/*
Shift filter states
Should be realized with modulo addressing on a DSP instead of a true buffer
shift
*/
FDKmemmove(anaQmf->FilterStates,
(FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels,
offset * sizeof(FIXP_QAS));
}
/*!
*
* \brief Perform complex-valued subband filtering of the time domain
* data of timeIn and stores the real part of the subband
* samples in rAnalysis, and the imaginary part in iAnalysis
* The qmf coefficient table is symmetric. The symmetry is expoited by
* shrinking the coefficient table to half the size. The addressing mode
* takes care of the symmetries.
*
*
* \sa PolyphaseFiltering
*/
void qmfAnalysisFiltering(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
QMF_SCALE_FACTOR *scaleFactor,
const INT_PCM_QMFIN *timeIn, /*!< Time signal */
const int timeIn_e, const int stride,
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
) {
int i;
int no_channels = anaQmf->no_channels;
scaleFactor->lb_scale =
-ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e;
scaleFactor->lb_scale -= anaQmf->filterScale;
for (i = 0; i < anaQmf->no_col; i++) {
FIXP_DBL *qmfImagSlot = NULL;
if (!(anaQmf->flags & QMF_FLAG_LP)) {
qmfImagSlot = qmfImag[i];
}
qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride,
pWorkBuffer);
timeIn += no_channels * stride;
} /* no_col loop i */
}
#endif /* QMF_PCM_H */

View File

@ -129,15 +129,13 @@ void scaleCplxValues(FIXP_DBL *r_dst, FIXP_DBL *i_dst, const FIXP_DBL *r_src,
void scaleValuesWithFactor(FIXP_DBL *vector, FIXP_DBL factor, INT len,
INT scalefactor);
void scaleValuesSaturate(FIXP_DBL *vector, INT len, INT scalefactor);
void scaleValuesSaturate(FIXP_DBL *dst, FIXP_DBL *src, INT len,
void scaleValuesSaturate(FIXP_DBL *dst, const FIXP_DBL *src, INT len,
INT scalefactor);
void scaleValuesSaturate(FIXP_SGL *dst, FIXP_DBL *src, INT len,
void scaleValuesSaturate(FIXP_SGL *dst, const FIXP_DBL *src, INT len,
INT scalefactor);
void scaleValuesSaturate(INT_PCM *dst, FIXP_DBL *src, INT len, INT scalefactor);
void scaleValuesSaturate(FIXP_SGL *vector, INT len, INT scalefactor);
void scaleValuesSaturate(FIXP_SGL *dst, FIXP_SGL *src, INT len,
void scaleValuesSaturate(FIXP_SGL *dst, const FIXP_SGL *src, INT len,
INT scalefactor);
void scaleValuesSaturate(INT_PCM *dst, INT_PCM *src, INT len, INT scalefactor);
INT getScalefactorShort(const SHORT *vector, INT len);
INT getScalefactorPCM(const INT_PCM *vector, INT len, INT stride);
INT getScalefactor(const FIXP_DBL *vector, INT len);

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -368,7 +368,10 @@ void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf, const UCHAR *RESTRICT inputBuffer,
UINT bTotal = 0;
UINT bToRead = (hBitBuf->bufBits - hBitBuf->ValidBits) >> 3;
UINT bToRead =
fMin(hBitBuf->bufBits,
(UINT)fMax(0, ((INT)hBitBuf->bufBits - (INT)hBitBuf->ValidBits))) >>
3;
UINT noOfBytes =
fMin(bToRead,
*bytesValid); //(bToRead < *bytesValid) ? bToRead : *bytesValid ;
@ -384,7 +387,7 @@ void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf, const UCHAR *RESTRICT inputBuffer,
bToRead * sizeof(UCHAR));
/* add noOfBits to number of valid bits in buffer */
hBitBuf->ValidBits += bToRead << 3;
hBitBuf->ValidBits = (UINT)((INT)hBitBuf->ValidBits + (INT)(bToRead << 3));
bTotal += bToRead;
inputBuffer += bToRead;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -104,10 +104,10 @@ amm-info@iis.fraunhofer.de
/* FDK tools library info */
#define FDK_TOOLS_LIB_VL0 3
#define FDK_TOOLS_LIB_VL1 0
#define FDK_TOOLS_LIB_VL1 1
#define FDK_TOOLS_LIB_VL2 0
#define FDK_TOOLS_LIB_TITLE "FDK Tools"
#ifdef __ANDROID__
#ifdef SUPPRESS_BUILD_DATE_INFO
#define FDK_TOOLS_LIB_BUILD_DATE ""
#define FDK_TOOLS_LIB_BUILD_TIME ""
#else

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -227,7 +227,7 @@ static inline int SpatialDecGetQmfBand(int paramBand, const UCHAR *tab) {
}
#define DUCKER_MAX_NRG_SCALE (24)
#define DUCKER_HEADROOM_BITS (3)
#define DUCKER_HEADROOM_BITS (2)
#define FILTER_SF (2)
@ -606,10 +606,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
dataImagIn += start;
dataRealOut += start;
dataImagOut += start;
#ifdef FUNCTION_DecorrFilterApplyPASS_func1
DecorrFilterApplyPASS_func1(i, dataRealIn, dataImagIn, dataRealOut,
dataImagOut, pDelayBuffer, offset);
#else
do {
FIXP_DBL delay_re, delay_im, real, imag;
@ -623,7 +619,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
*dataImagOut++ = delay_im;
pDelayBuffer += offset;
} while (--i != 0);
#endif
}
}
@ -1061,24 +1056,15 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
if (maxVal == FL2FXCONST_DBL(-1.0f)) {
#ifdef FUNCTION_DuckerCalcEnergy_func2
maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
maxHybBand, maxHybridBand);
#else
FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
for (qs = startHybBand; qs <= maxHybBand; qs++) {
localMaxVal |= fAbs(inputReal[qs]);
localMaxVal |= fAbs(inputImag[qs]);
}
for (; qs <= maxHybridBand; qs++) {
localMaxVal |= fAbs(inputReal[qs]);
}
maxVal = localMaxVal;
#endif
clz = fMin(getScalefactor(&inputReal[startHybBand],
fMax(0, maxHybridBand - startHybBand + 1)),
getScalefactor(&inputImag[startHybBand],
fMax(0, maxHybBand - startHybBand + 1)));
} else {
clz = CntLeadingZeros(maxVal) - 1;
}
clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
*nrgScale = (SCHAR)clz << 1;
/* Initialize pb since it would stay uninitialized for the case startHybBand
@ -1086,9 +1072,10 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
pb = SpatialDecGetProcessingBand(maxHybBand, self->mapHybBands2ProcBands);
for (qs = startHybBand; qs <= maxHybBand; qs++) {
pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
energy[pb] =
fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
fPow2Div2(inputImag[qs] << clz));
energy[pb] = SATURATE_LEFT_SHIFT(
(energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
(fPow2Div2(inputImag[qs] << clz) >> 1),
1, DFRACT_BITS);
}
pb++;
@ -1112,43 +1099,29 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
maxVal = inputMaxVal;
if (maxVal == FL2FXCONST_DBL(-1.0f)) {
#ifdef FUNCTION_DuckerCalcEnergy_func2
maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
maxHybBand, maxHybridBand);
#else
FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
for (qs = startHybBand; qs <= maxHybBand; qs++) {
localMaxVal |= fAbs(inputReal[qs]);
localMaxVal |= fAbs(inputImag[qs]);
}
for (; qs <= maxHybridBand; qs++) {
localMaxVal |= fAbs(inputReal[qs]);
}
maxVal = localMaxVal;
#endif
clz = fMin(getScalefactor(&inputReal[startHybBand],
fMax(0, maxHybridBand - startHybBand + 1)),
getScalefactor(&inputImag[startHybBand],
fMax(0, maxHybBand - startHybBand + 1)));
} else {
clz = CntLeadingZeros(maxVal) - 1;
}
clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
*nrgScale = (SCHAR)clz << 1;
#ifdef FUNCTION_DuckerCalcEnergy_func4
DuckerCalcEnergy_func4(inputReal, inputImag, energy,
self->mapHybBands2ProcBands, clz, startHybBand,
maxHybBand, maxHybridBand);
#else
for (qs = startHybBand; qs <= maxHybBand; qs++) {
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
energy[pb] =
fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
fPow2Div2(inputImag[qs] << clz));
energy[pb] = SATURATE_LEFT_SHIFT(
(energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
(fPow2Div2(inputImag[qs] << clz) >> 1),
1, DFRACT_BITS);
}
for (; qs <= maxHybridBand; qs++) {
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
energy[pb] = fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz));
}
#endif /* FUNCTION_DuckerCalcEnergy_func4 */
}
{
@ -1295,10 +1268,6 @@ static INT DuckerApply(DUCKER_INSTANCE *const self,
}
}
#ifdef FUNCTION_DuckerApply_func1
qs = DuckerApply_func1(qs, hybBands, qs_next, outputReal, outputImag,
duckGain);
#else
/* general gain*output section */
if (qs < hybBands) { /* true for about 39% */
for (; qs < qs_next; qs++) { /* runs about 2 times */
@ -1310,7 +1279,6 @@ static INT DuckerApply(DUCKER_INSTANCE *const self,
outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
}
}
#endif
} /* pb */
self->headroomSmoothDirRevNrg =

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -142,11 +142,12 @@ amm-info@iis.fraunhofer.de
} /* How to arrange the packed values. */
struct FDK_HYBRID_SETUP {
UCHAR nrQmfBands; /*!< Number of QMF bands to be converted to hybrid. */
UCHAR nHybBands[3]; /*!< Number of Hybrid bands generated by nrQmfBands. */
SCHAR kHybrid[3]; /*!< Filter configuration of each QMF band. */
UCHAR protoLen; /*!< Prototype filter length. */
UCHAR filterDelay; /*!< Delay caused by hybrid filter. */
UCHAR nrQmfBands; /*!< Number of QMF bands to be converted to hybrid. */
UCHAR nHybBands[3]; /*!< Number of Hybrid bands generated by nrQmfBands. */
UCHAR synHybScale[3]; /*!< Headroom needed in hybrid synthesis filterbank. */
SCHAR kHybrid[3]; /*!< Filter configuration of each QMF band. */
UCHAR protoLen; /*!< Prototype filter length. */
UCHAR filterDelay; /*!< Delay caused by hybrid filter. */
const INT
*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,
5, 6, 7, 8, 9, 10, 11, 12};
static const FDK_HYBRID_SETUP setup_3_16 = {3, {8, 4, 4}, {8, 4, 4},
13, (13 - 1) / 2, ringbuffIdxTab};
static const FDK_HYBRID_SETUP setup_3_12 = {3, {8, 2, 2}, {8, 2, 2},
13, (13 - 1) / 2, ringbuffIdxTab};
static const FDK_HYBRID_SETUP setup_3_10 = {3, {6, 2, 2}, {-8, -2, 2},
13, (13 - 1) / 2, ringbuffIdxTab};
static const FDK_HYBRID_SETUP setup_3_16 = {
3, {8, 4, 4}, {4, 3, 3}, {8, 4, 4}, 13, (13 - 1) / 2, ringbuffIdxTab};
static const FDK_HYBRID_SETUP setup_3_12 = {
3, {8, 2, 2}, {4, 2, 2}, {8, 2, 2}, 13, (13 - 1) / 2, ringbuffIdxTab};
static const FDK_HYBRID_SETUP setup_3_10 = {
3, {6, 2, 2}, {3, 2, 2}, {-8, -2, 2}, 13, (13 - 1) / 2, ringbuffIdxTab};
static const FIXP_HTP HybFilterCoef8[] = {
HTCP(0x10000000, 0x00000000), HTCP(0x0df26407, 0xfa391882),
@ -477,17 +478,18 @@ void FDKhybridSynthesisApply(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,
*/
for (k = 0; k < nrQmfBandsLF; k++) {
const int nHybBands = hSynthesisHybFilter->pSetup->nHybBands[k];
const int scale = hSynthesisHybFilter->pSetup->synHybScale[k];
FIXP_DBL accu1 = FL2FXCONST_DBL(0.f);
FIXP_DBL accu2 = FL2FXCONST_DBL(0.f);
/* Perform hybrid filtering. */
for (n = 0; n < nHybBands; n++) {
accu1 += pHybridReal[hybOffset + n];
accu2 += pHybridImag[hybOffset + n];
accu1 += pHybridReal[hybOffset + n] >> scale;
accu2 += pHybridImag[hybOffset + n] >> scale;
}
pQmfReal[k] = accu1;
pQmfImag[k] = accu2;
pQmfReal[k] = SATURATE_LEFT_SHIFT(accu1, scale, DFRACT_BITS);
pQmfImag[k] = SATURATE_LEFT_SHIFT(accu2, scale, DFRACT_BITS);
hybOffset += nHybBands;
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -106,35 +106,31 @@ amm-info@iis.fraunhofer.de
#include "common_fix.h"
#define WORKBUFFER1_TAG 0
#define WORKBUFFER2_TAG 1
#define WORKBUFFER3_TAG 4
#define WORKBUFFER4_TAG 5
#define WORKBUFFER5_TAG 6
#define WORKBUFFER6_TAG 7
#define WORKBUFFER7_TAG 8
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL, QMF_WB_SECTION_SIZE,
SECT_DATA_L1, WORKBUFFER1_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL, QMF_WB_SECTION_SIZE,
SECT_DATA_L2, WORKBUFFER2_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL, QMF_WB_SECTION_SIZE,
SECT_DATA_L2, WORKBUFFER3_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL, QMF_WB_SECTION_SIZE,
SECT_DATA_L2, WORKBUFFER4_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL, QMF_WB_SECTION_SIZE,
SECT_DATA_L2, WORKBUFFER5_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL, QMF_WB_SECTION_SIZE,
SECT_DATA_L2, WORKBUFFER6_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL, QMF_WB_SECTION_SIZE,
SECT_DATA_L2, WORKBUFFER7_TAG)
/*! Analysis states buffer. <br>
Dimension: #((8) + (1)) */
C_ALLOC_MEM2(AnaQmfStates, FIXP_QAS, 10 * QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS,
((8) + (1)))
C_AALLOC_MEM2(AnaQmfStates, FIXP_DBL, 10 * QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS,
((8) + (1)))
/*! Synthesis states buffer. <br>
Dimension: #((8) + (1)) */
C_ALLOC_MEM2(SynQmfStates, FIXP_QSS, 9 * QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS,
((8) + (1)))
C_AALLOC_MEM2(SynQmfStates, FIXP_QSS, 9 * QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS,
((8) + (1)))
/*! Pointer to real qmf data for each time slot. <br>
Dimension: #((8) + (1)) */
@ -156,18 +152,17 @@ C_AALLOC_MEM2(QmfOverlapBuffer, FIXP_DBL,
/*! Analysis states buffer. <br>
Dimension: #((8) + (1)) */
C_ALLOC_MEM2(AnaQmfStates16, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_16,
((8) + (1)))
C_AALLOC_MEM2(AnaQmfStates16, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_16,
((8) + (1)))
/*! Analysis states buffer. <br>
Dimension: #((8) + (1)) */
C_AALLOC_MEM2(AnaQmfStates24, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24,
((8) + (1)))
/*! Analysis states buffer. <br>
Dimension: #((8) + (1)) */
C_ALLOC_MEM2(AnaQmfStates24, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24,
((8) + (1)))
/*! Analysis states buffer. <br>
Dimension: #((8) + (1)) */
C_ALLOC_MEM2(AnaQmfStates32, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32,
((8) + (1)))
C_AALLOC_MEM2(AnaQmfStates32, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32,
((8) + (1)))
/*! Pointer to real qmf data for each time slot. <br>
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) {
for (; b < fMin(lsb, stop_band); b++) {
pQmfOutReal[b] = scaleValue(real[b], lb_sf);
pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf);
}
for (; b < fMin(usb, stop_band); b++) {
pQmfOutReal[b] = scaleValue(real[b], hb_sf);
pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf);
}
for (; b < stop_band; b++) {
pQmfOutReal[b] = (FIXP_DBL)0;
@ -653,12 +648,12 @@ void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
} else {
FDK_ASSERT(imag != NULL);
for (; b < fMin(lsb, stop_band); b++) {
pQmfOutReal[b] = scaleValue(real[b], lb_sf);
pQmfOutImag[b] = scaleValue(imag[b], lb_sf);
pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf);
pQmfOutImag[b] = scaleValueSaturate(imag[b], lb_sf);
}
for (; b < fMin(usb, stop_band); b++) {
pQmfOutReal[b] = scaleValue(real[b], hb_sf);
pQmfOutImag[b] = scaleValue(imag[b], hb_sf);
pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf);
pQmfOutImag[b] = scaleValueSaturate(imag[b], hb_sf);
}
for (; b < stop_band; b++) {
pQmfOutReal[b] = (FIXP_DBL)0;
@ -950,7 +945,7 @@ QMF_DOMAIN_ERROR FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd) {
if ((size > 4 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[4] == NULL)) {
/* get work buffer of size QMF_WB_SECTION_SIZE */
pWorkBuffer[4] = GetQmfWorkBufferCore5();
pWorkBuffer[4] = GetQmfWorkBufferCore7();
}
/* 8. distribute workbuffer over processing channels */
@ -996,7 +991,7 @@ static void FDK_QmfDomain_FreeWorkBuffer(HANDLE_FDK_QMF_DOMAIN hqd) {
if (pWorkBuffer[1]) FreeQmfWorkBufferCore1(&pWorkBuffer[1]);
if (pWorkBuffer[2]) FreeQmfWorkBufferCore3(&pWorkBuffer[2]);
if (pWorkBuffer[3]) FreeQmfWorkBufferCore4(&pWorkBuffer[3]);
if (pWorkBuffer[4]) FreeQmfWorkBufferCore5(&pWorkBuffer[4]);
if (pWorkBuffer[4]) FreeQmfWorkBufferCore7(&pWorkBuffer[4]);
}
void FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd) {

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -489,18 +489,18 @@ void dst_IV(FIXP_DBL *pDat, int L, int *pDat_e) {
for (i = 0; i < M - 1; i += 2, pDat_0 += 2, pDat_1 -= 2) {
FIXP_DBL accu1, accu2, accu3, accu4;
accu1 = pDat_1[1];
accu2 = -pDat_0[0];
accu3 = pDat_0[1];
accu4 = -pDat_1[0];
accu1 = pDat_1[1] >> 1;
accu2 = -(pDat_0[0] >> 1);
accu3 = pDat_0[1] >> 1;
accu4 = -(pDat_1[0] >> 1);
cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
pDat_0[0] = accu2 >> 1;
pDat_0[1] = accu1 >> 1;
pDat_1[0] = accu4 >> 1;
pDat_1[1] = -(accu3 >> 1);
pDat_0[0] = accu2;
pDat_0[1] = accu1;
pDat_1[0] = accu4;
pDat_1[1] = -accu3;
}
if (M & 1) {
FIXP_DBL accu1, accu2;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -650,6 +650,12 @@ FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
INT ans_lg2_e, baselg2_e;
FIXP_DBL base_lg2, ans_lg2, result;
if (base_m <= (FIXP_DBL)0) {
result = (FIXP_DBL)0;
*result_e = 0;
return result;
}
/* Calc log2 of base */
base_lg2 = fLog2(base_m, base_e, &baselg2_e);

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -569,7 +569,7 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum,
*/
for (i = 0; i < hMdct->prev_nr; i++) {
FIXP_DBL x = -(*pOvl--);
*pOut0 = IMDCT_SCALE_DBL(x + hMdct->pFacZir[i]);
*pOut0 = fAddSaturate(x, IMDCT_SCALE_DBL(hMdct->pFacZir[i]));
pOut0++;
}
hMdct->pFacZir = NULL;
@ -678,7 +678,7 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum,
FIXP_DBL *pOut = pOut0 - fl / 2;
FDK_ASSERT(fl / 2 <= 128);
for (i = 0; i < fl / 2; i++) {
pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
pOut[i] = fAddSaturate(pOut[i], IMDCT_SCALE_DBL(hMdct->pFacZir[i]));
}
hMdct->pFacZir = NULL;
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -147,88 +147,6 @@ amm-info@iis.fraunhofer.de
/* moved to qmf_pcm.h: -> qmfSynPrototypeFirSlot_NonSymmetric */
/* moved to qmf_pcm.h: -> qmfSynthesisFilteringSlot */
#ifndef FUNCTION_qmfAnaPrototypeFirSlot
/*!
\brief Perform Analysis Prototype Filtering on a single slot of input data.
*/
static void qmfAnaPrototypeFirSlot(
FIXP_DBL *analysisBuffer,
INT no_channels, /*!< Number channels of analysis filter */
const FIXP_PFT *p_filter, INT p_stride, /*!< Stride of analysis filter */
FIXP_QAS *RESTRICT pFilterStates) {
INT k;
FIXP_DBL accu;
const FIXP_PFT *RESTRICT p_flt = p_filter;
FIXP_DBL *RESTRICT pData_0 = analysisBuffer + 2 * no_channels - 1;
FIXP_DBL *RESTRICT pData_1 = analysisBuffer;
FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates;
FIXP_QAS *RESTRICT sta_1 =
(FIXP_QAS *)pFilterStates + (2 * QMF_NO_POLY * no_channels) - 1;
INT pfltStep = QMF_NO_POLY * (p_stride);
INT staStep1 = no_channels << 1;
INT staStep2 = (no_channels << 3) - 1; /* Rewind one less */
/* FIR filters 127..64 0..63 */
for (k = 0; k < no_channels; k++) {
accu = fMultDiv2(p_flt[0], *sta_1);
sta_1 -= staStep1;
accu += fMultDiv2(p_flt[1], *sta_1);
sta_1 -= staStep1;
accu += fMultDiv2(p_flt[2], *sta_1);
sta_1 -= staStep1;
accu += fMultDiv2(p_flt[3], *sta_1);
sta_1 -= staStep1;
accu += fMultDiv2(p_flt[4], *sta_1);
*pData_1++ = (accu << 1);
sta_1 += staStep2;
p_flt += pfltStep;
accu = fMultDiv2(p_flt[0], *sta_0);
sta_0 += staStep1;
accu += fMultDiv2(p_flt[1], *sta_0);
sta_0 += staStep1;
accu += fMultDiv2(p_flt[2], *sta_0);
sta_0 += staStep1;
accu += fMultDiv2(p_flt[3], *sta_0);
sta_0 += staStep1;
accu += fMultDiv2(p_flt[4], *sta_0);
*pData_0-- = (accu << 1);
sta_0 -= staStep2;
}
}
#endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */
#ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric
/*!
\brief Perform Analysis Prototype Filtering on a single slot of input data.
*/
static void qmfAnaPrototypeFirSlot_NonSymmetric(
FIXP_DBL *analysisBuffer,
int no_channels, /*!< Number channels of analysis filter */
const FIXP_PFT *p_filter, int p_stride, /*!< Stride of analysis filter */
FIXP_QAS *RESTRICT pFilterStates) {
const FIXP_PFT *RESTRICT p_flt = p_filter;
int p, k;
for (k = 0; k < 2 * no_channels; k++) {
FIXP_DBL accu = (FIXP_DBL)0;
p_flt += QMF_NO_POLY * (p_stride - 1);
/*
Perform FIR-Filter
*/
for (p = 0; p < QMF_NO_POLY; p++) {
accu += fMultDiv2(*p_flt++, pFilterStates[2 * no_channels * p]);
}
analysisBuffer[2 * no_channels - 1 - k] = (accu << 1);
pFilterStates++;
}
}
#endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */
/*!
*
* \brief Perform real-valued forward modulation of the time domain
@ -244,7 +162,7 @@ static void qmfForwardModulationLP_even(
int i;
int L = anaQmf->no_channels;
int M = L >> 1;
int scale;
int scale = 0;
FIXP_DBL accu;
const FIXP_DBL *timeInTmp1 = (FIXP_DBL *)&timeIn[3 * M];
@ -381,211 +299,6 @@ static void qmfForwardModulationHQ(
}
#endif /* FUNCTION_qmfForwardModulationHQ */
/*
* \brief Perform one QMF slot analysis of the time domain data of timeIn
* with specified stride and stores the real part of the subband
* samples in rSubband, and the imaginary part in iSubband
*
* Note: anaQmf->lsb can be greater than anaQmf->no_channels in case
* of implicit resampling (USAC with reduced 3/4 core frame length).
*/
#if (SAMPLE_BITS != DFRACT_BITS) && (QAS_BITS == DFRACT_BITS)
void qmfAnalysisFilteringSlot(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
FIXP_DBL *qmfReal, /*!< Low and High band, real */
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
const LONG *RESTRICT timeIn, /*!< Pointer to input */
const int stride, /*!< stride factor of input */
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
) {
int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1);
/*
Feed time signal into oldest anaQmf->no_channels states
*/
{
FIXP_DBL *FilterStatesAnaTmp = ((FIXP_DBL *)anaQmf->FilterStates) + offset;
/* Feed and scale actual time in slot */
for (int i = anaQmf->no_channels >> 1; i != 0; i--) {
/* Place INT_PCM value left aligned in scaledTimeIn */
*FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
timeIn += stride;
*FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
timeIn += stride;
}
}
if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels,
anaQmf->p_filter, anaQmf->p_stride,
(FIXP_QAS *)anaQmf->FilterStates);
} else {
qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter,
anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates);
}
if (anaQmf->flags & QMF_FLAG_LP) {
if (anaQmf->flags & QMF_FLAG_CLDFB)
qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal);
else
qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal);
} else {
qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag);
}
/*
Shift filter states
Should be realized with modulo adressing on a DSP instead of a true buffer
shift
*/
FDKmemmove(anaQmf->FilterStates,
(FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels,
offset * sizeof(FIXP_QAS));
}
#endif
void qmfAnalysisFilteringSlot(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
FIXP_DBL *qmfReal, /*!< Low and High band, real */
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
const INT_PCM *RESTRICT timeIn, /*!< Pointer to input */
const int stride, /*!< stride factor of input */
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
) {
int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1);
/*
Feed time signal into oldest anaQmf->no_channels states
*/
{
FIXP_QAS *FilterStatesAnaTmp = ((FIXP_QAS *)anaQmf->FilterStates) + offset;
/* Feed and scale actual time in slot */
for (int i = anaQmf->no_channels >> 1; i != 0; i--) {
/* Place INT_PCM value left aligned in scaledTimeIn */
#if (QAS_BITS == SAMPLE_BITS)
*FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
timeIn += stride;
*FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
timeIn += stride;
#elif (QAS_BITS > SAMPLE_BITS)
*FilterStatesAnaTmp++ = ((FIXP_QAS)*timeIn) << (QAS_BITS - SAMPLE_BITS);
timeIn += stride;
*FilterStatesAnaTmp++ = ((FIXP_QAS)*timeIn) << (QAS_BITS - SAMPLE_BITS);
timeIn += stride;
#else
*FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn) >> (SAMPLE_BITS - QAS_BITS));
timeIn += stride;
*FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn) >> (SAMPLE_BITS - QAS_BITS));
timeIn += stride;
#endif
}
}
if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels,
anaQmf->p_filter, anaQmf->p_stride,
(FIXP_QAS *)anaQmf->FilterStates);
} else {
qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter,
anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates);
}
if (anaQmf->flags & QMF_FLAG_LP) {
if (anaQmf->flags & QMF_FLAG_CLDFB)
qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal);
else
qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal);
} else {
qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag);
}
/*
Shift filter states
Should be realized with modulo adressing on a DSP instead of a true buffer
shift
*/
FDKmemmove(anaQmf->FilterStates,
(FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels,
offset * sizeof(FIXP_QAS));
}
/*!
*
* \brief Perform complex-valued subband filtering of the time domain
* data of timeIn and stores the real part of the subband
* samples in rAnalysis, and the imaginary part in iAnalysis
* The qmf coefficient table is symmetric. The symmetry is expoited by
* shrinking the coefficient table to half the size. The addressing mode
* takes care of the symmetries.
*
*
* \sa PolyphaseFiltering
*/
#if (SAMPLE_BITS != DFRACT_BITS) && (QAS_BITS == DFRACT_BITS)
void qmfAnalysisFiltering(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
QMF_SCALE_FACTOR *scaleFactor, const LONG *timeIn, /*!< Time signal */
const int timeIn_e, const int stride,
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
) {
int i;
int no_channels = anaQmf->no_channels;
scaleFactor->lb_scale =
-ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e;
scaleFactor->lb_scale -= anaQmf->filterScale;
for (i = 0; i < anaQmf->no_col; i++) {
FIXP_DBL *qmfImagSlot = NULL;
if (!(anaQmf->flags & QMF_FLAG_LP)) {
qmfImagSlot = qmfImag[i];
}
qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride,
pWorkBuffer);
timeIn += no_channels * stride;
} /* no_col loop i */
}
#endif
void qmfAnalysisFiltering(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
QMF_SCALE_FACTOR *scaleFactor, const INT_PCM *timeIn, /*!< Time signal */
const int timeIn_e, const int stride,
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
) {
int i;
int no_channels = anaQmf->no_channels;
scaleFactor->lb_scale =
-ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e;
scaleFactor->lb_scale -= anaQmf->filterScale;
for (i = 0; i < anaQmf->no_col; i++) {
FIXP_DBL *qmfImagSlot = NULL;
if (!(anaQmf->flags & QMF_FLAG_LP)) {
qmfImagSlot = qmfImag[i];
}
qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride,
pWorkBuffer);
timeIn += no_channels * stride;
} /* no_col loop i */
}
/*!
*
* \brief Perform low power inverse modulation of the subband
@ -603,15 +316,15 @@ inline static void qmfInverseModulationLP_even(
int i;
int L = synQmf->no_channels;
int M = L >> 1;
int scale;
int scale = 0;
FIXP_DBL tmp;
FIXP_DBL *RESTRICT tReal = pTimeOut;
FIXP_DBL *RESTRICT tImag = pTimeOut + L;
/* Move input to output vector with offset */
scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand);
scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb, scaleFactorLowBand);
scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
FDKmemclear(&tReal[0 + synQmf->usb], (L - synQmf->usb) * sizeof(FIXP_DBL));
/* Dct type-2 transform */
@ -662,9 +375,9 @@ inline static void qmfInverseModulationLP_odd(
int shift = 0;
/* Move input to output vector with offset */
scaleValues(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
scaleValues(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
scaleValuesSaturate(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
scaleValuesSaturate(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
FDKmemclear(pTimeOut + M + synQmf->usb, (L - synQmf->usb) * sizeof(FIXP_DBL));
dct_IV(pTimeOut + M, L, &shift);
@ -698,26 +411,27 @@ inline static void qmfInverseModulationHQ(
FIXP_DBL *RESTRICT tImag = pWorkBuffer + L;
if (synQmf->flags & QMF_FLAG_CLDFB) {
for (i = 0; i < synQmf->lsb; i++) {
cplxMult(&tImag[i], &tReal[i], scaleValue(qmfImag[i], scaleFactorLowBand),
scaleValue(qmfReal[i], scaleFactorLowBand), synQmf->t_cos[i],
synQmf->t_sin[i]);
}
for (; i < synQmf->usb; i++) {
cplxMult(&tImag[i], &tReal[i],
scaleValue(qmfImag[i], scaleFactorHighBand),
scaleValue(qmfReal[i], scaleFactorHighBand), synQmf->t_cos[i],
synQmf->t_sin[i]);
for (i = 0; i < synQmf->usb; i++) {
cplxMultDiv2(&tImag[i], &tReal[i], qmfImag[i], qmfReal[i],
synQmf->t_cos[i], synQmf->t_sin[i]);
}
scaleValuesSaturate(&tReal[0], synQmf->lsb, scaleFactorLowBand + 1);
scaleValuesSaturate(&tReal[0 + synQmf->lsb], synQmf->usb - synQmf->lsb,
scaleFactorHighBand + 1);
scaleValuesSaturate(&tImag[0], synQmf->lsb, scaleFactorLowBand + 1);
scaleValuesSaturate(&tImag[0 + synQmf->lsb], synQmf->usb - synQmf->lsb,
scaleFactorHighBand + 1);
}
if ((synQmf->flags & QMF_FLAG_CLDFB) == 0) {
scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand);
scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
scaleValues(&tImag[0], &qmfImag[0], synQmf->lsb, (int)scaleFactorLowBand);
scaleValues(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb,
scaleFactorLowBand);
scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
scaleValuesSaturate(&tImag[0], &qmfImag[0], synQmf->lsb,
scaleFactorLowBand);
scaleValuesSaturate(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
}
FDKmemclear(&tReal[synQmf->usb],
@ -996,35 +710,6 @@ static inline void qmfAdaptFilterStates(
}
}
/*!
*
* \brief Create QMF filter bank instance
*
*
* \return 0 if succesful
*
*/
int qmfInitAnalysisFilterBank(
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */
FIXP_QAS *pFilterStates, /*!< Handle to filter states */
int noCols, /*!< Number of timeslots per frame */
int lsb, /*!< lower end of QMF */
int usb, /*!< upper end of QMF */
int no_channels, /*!< Number of channels (bands) */
int flags) /*!< Low Power flag */
{
int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb,
no_channels, flags, 0);
if (!(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL)) {
FDKmemclear(h_Qmf->FilterStates,
(2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QAS));
}
FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb);
return err;
}
/*!
*
* \brief Create QMF filter bank instance
@ -1128,8 +813,21 @@ void qmfChangeOutGain(
synQmf->outGain_e = outputGainScale;
}
/* When QMF_16IN_32OUT is set, synthesis functions for 16 and 32 bit parallel
* output is compiled */
#define INT_PCM_QMFOUT INT_PCM
#define SAMPLE_BITS_QMFOUT SAMPLE_BITS
#include "qmf_pcm.h"
#if SAMPLE_BITS == 16
/* also create a 32 bit output version */
#undef INT_PCM_QMFOUT
#undef SAMPLE_BITS_QMFOUT
#undef QMF_PCM_H
#undef FIXP_QAS
#undef QAS_BITS
#undef INT_PCM_QMFIN
#define INT_PCM_QMFOUT LONG
#define SAMPLE_BITS_QMFOUT 32
#define FIXP_QAS FIXP_DBL
#define QAS_BITS 32
#define INT_PCM_QMFIN LONG
#include "qmf_pcm.h"
#endif

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -250,10 +250,10 @@ void scaleValuesSaturate(FIXP_DBL *vector, /*!< Vector */
*/
#define FUNCTION_scaleValuesSaturate_DBL_DBL
SCALE_INLINE
void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
FIXP_DBL *src, /*!< Input */
INT len, /*!< Length */
INT scalefactor /*!< Scalefactor */
void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
const FIXP_DBL *src, /*!< Input */
INT len, /*!< Length */
INT scalefactor /*!< Scalefactor */
) {
INT i;
@ -285,10 +285,10 @@ void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
*/
#define FUNCTION_scaleValuesSaturate_SGL_DBL
SCALE_INLINE
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
FIXP_DBL *src, /*!< Input */
INT len, /*!< Length */
INT scalefactor) /*!< Scalefactor */
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
const FIXP_DBL *src, /*!< Input */
INT len, /*!< Length */
INT scalefactor) /*!< Scalefactor */
{
INT i;
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
SCALE_INLINE
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
FIXP_SGL *src, /*!< Input */
INT len, /*!< Length */
INT scalefactor /*!< Scalefactor */
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
const FIXP_SGL *src, /*!< Input */
INT len, /*!< Length */
INT scalefactor /*!< Scalefactor */
) {
INT i;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -213,8 +213,8 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts,
goto bail;
}
FDKcrcReset(&pAdts->crcInfo);
if (!bs.protection_absent) {
FDKcrcReset(&pAdts->crcInfo);
FDKpushBack(hBs, 56); /* complete fixed and variable header! */
crcReg = FDKcrcStartReg(&pAdts->crcInfo, hBs, 0);
FDKpushFor(hBs, 56);
@ -314,15 +314,55 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts,
if (bs.channel_config == 0) {
int pceBits = 0;
UINT alignAnchor = FDKgetValidBits(hBs);
CProgramConfig tmpPce;
if (FDKreadBits(hBs, 3) == ID_PCE) {
/* Got luck! Parse the PCE */
crcReg = adtsRead_CrcStartReg(pAdts, hBs, 0);
CProgramConfig_Read(&pAsc->m_progrConfigElement, hBs, alignAnchor);
CProgramConfig_Init(&tmpPce);
CProgramConfig_Read(&tmpPce, hBs, alignAnchor);
if (CProgramConfig_IsValid(&tmpPce)) {
if (CProgramConfig_IsValid(&oldPce)) {
/* Compare the new and the old PCE (tags ignored) */
switch (CProgramConfig_Compare(&tmpPce, &oldPce)) {
case 0: /* Nothing to do because PCE matches the old one exactly. */
case 1: /* Channel configuration not changed. Just new metadata. */
FDKmemcpy(&pAsc->m_progrConfigElement, &tmpPce,
sizeof(CProgramConfig));
break;
case 2: /* The number of channels are identical but not the config
*/
case -1: /* The channel configuration is completely different */
default:
FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce,
sizeof(CProgramConfig));
FDKpushBack(hBs, adtsHeaderLength);
return TRANSPORTDEC_PARSE_ERROR;
}
} else {
FDKmemcpy(&pAsc->m_progrConfigElement, &tmpPce,
sizeof(CProgramConfig));
}
} else {
if (CProgramConfig_IsValid(&oldPce)) {
FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce,
sizeof(CProgramConfig));
} else {
FDKpushBack(hBs, adtsHeaderLength);
return TRANSPORTDEC_PARSE_ERROR;
}
}
adtsRead_CrcEndReg(pAdts, hBs, crcReg);
pceBits = alignAnchor - FDKgetValidBits(hBs);
pceBits = (INT)alignAnchor - (INT)FDKgetValidBits(hBs);
adtsHeaderLength += pceBits;
if (pceBits > (INT)alignAnchor) {
goto bail;
}
/* store the number of PCE bits */
bs.num_pce_bits = pceBits;
} else {

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -1325,9 +1325,9 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
CSTpCallBacks *cb) {
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig;
int eldExtType;
UINT eldExtType;
int eldExtLen, len, cnt, ldSbrLen = 0, eldExtLenSum, numSbrHeader = 0,
sbrIndex;
sbrIndex, eldExtCnt = 0;
unsigned char downscale_fill_nibble;
@ -1394,9 +1394,8 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
eldExtLenSum = FDKgetValidBits(hBs);
esc->m_downscaledSamplingFrequency = asc->m_samplingFrequency;
/* parse ExtTypeConfigData */
while (
((eldExtType = FDKreadBits(hBs, 4)) != ELDEXT_TERM) &&
((INT)FDKgetValidBits(hBs) >= 0)) {
while (((eldExtType = FDKreadBits(hBs, 4)) != ELDEXT_TERM) &&
((INT)FDKgetValidBits(hBs) >= 0) && (eldExtCnt++ < 15)) {
eldExtLen = len = FDKreadBits(hBs, 4);
if (len == 0xf) {
len = FDKreadBits(hBs, 8);
@ -1440,7 +1439,8 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
UCHAR tmpDownscaleFreqIdx;
esc->m_downscaledSamplingFrequency =
getSampleRate(hBs, &tmpDownscaleFreqIdx, 4);
if (esc->m_downscaledSamplingFrequency == 0) {
if (esc->m_downscaledSamplingFrequency == 0 ||
esc->m_downscaledSamplingFrequency > 96000) {
return TRANSPORTDEC_PARSE_ERROR;
}
downscale_fill_nibble = FDKreadBits(hBs, 4);
@ -1454,6 +1454,9 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
break;
}
}
if (eldExtType != ELDEXT_TERM) {
return TRANSPORTDEC_PARSE_ERROR;
}
if ((INT)FDKgetValidBits(hBs) < 0) {
return TRANSPORTDEC_PARSE_ERROR;
@ -1947,6 +1950,9 @@ static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc,
INT nbits = (INT)FDKgetValidBits(hBs);
usacSamplingFrequency = getSampleRate(hBs, &asc->m_samplingFrequencyIndex, 5);
if (usacSamplingFrequency == 0 || usacSamplingFrequency > 96000) {
return TRANSPORTDEC_PARSE_ERROR;
}
asc->m_samplingFrequency = (UINT)usacSamplingFrequency;
coreSbrFrameLengthIndex = FDKreadBits(hBs, 3);
@ -2026,7 +2032,8 @@ static TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(
self->m_extensionSamplingFrequency = getSampleRate(
bs, &self->m_extensionSamplingFrequencyIndex, 4);
if ((INT)self->m_extensionSamplingFrequency <= 0) {
if (self->m_extensionSamplingFrequency == 0 ||
self->m_extensionSamplingFrequency > 96000) {
return TRANSPORTDEC_PARSE_ERROR;
}
}
@ -2138,6 +2145,24 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
self->m_channelConfiguration = FDKreadBits(bs, 4);
/* MPEG-04 standard ISO/IEC 14496-3: channelConfiguration == 0 is reserved
in er_raw_data_block (table 4.19) and er_raw_data_block_eld (table 4.75)
MPEG-04 conformance ISO/IEC 14496-4: channelConfiguration == 0 is not
permitted for AOT_ER_AAC_LC, AOT_ER_AAC_LTP, AOT_ER_AAC_LD,
AOT_ER_AAC_SCAL (chapter 6.6.4.1.2.1.1) */
if ((self->m_channelConfiguration == 0) &&
((self->m_aot == AOT_ER_AAC_LC) || (self->m_aot == AOT_ER_AAC_LTP) ||
(self->m_aot == AOT_ER_AAC_LD) || (self->m_aot == AOT_ER_AAC_SCAL) ||
(self->m_aot == AOT_ER_AAC_ELD))) {
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
}
/* MPEG-04 conformance ISO/IEC 14496-4: channelConfiguration > 2 is not
* permitted for AOT_AAC_SCAL and AOT_ER_AAC_SCAL (chapter 6.6.4.1.2.1.1) */
if ((self->m_channelConfiguration > 2) &&
((self->m_aot == AOT_AAC_SCAL) || (self->m_aot == AOT_ER_AAC_SCAL))) {
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
}
/* SBR extension ( explicit non-backwards compatible mode ) */
self->m_sbrPresentFlag = 0;
self->m_psPresentFlag = 0;
@ -2152,6 +2177,10 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
self->m_extensionSamplingFrequency =
getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
if (self->m_extensionSamplingFrequency == 0 ||
self->m_extensionSamplingFrequency > 96000) {
return TRANSPORTDEC_PARSE_ERROR;
}
self->m_aot = getAOT(bs);
switch (self->m_aot) {

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -367,10 +367,10 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig(
}
if (pLatmDemux->m_AudioMuxVersion == 1) {
FDK_BITSTREAM tmpBs;
UINT ascLen = 0;
INT ascLen = 0;
ascLen = CLatmDemux_GetValue(bs);
/* The ascLen could be wrong, so check if validBits<=bufBits*/
if (ascLen > FDKgetValidBits(bs)) {
if (ascLen < 0 || ascLen > (INT)FDKgetValidBits(bs)) {
ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
goto bail;
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -482,7 +482,8 @@ TRANSPORTDEC_ERROR transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,
for (int i = 0; i < 2; i++) {
if (i > 0) {
FDKpushBack(hBs, newConfigLength * 8 - FDKgetValidBits(hBs));
FDKpushBack(hBs,
(INT)newConfigLength * 8 - (INT)FDKgetValidBits(hBs));
configMode = AC_CM_ALLOC_MEM;
}
/* config transport decoder */
@ -663,10 +664,14 @@ TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
if (*pBytesValid == 0) {
/* nothing to do */
return TRANSPORTDEC_OK;
}
if (hTp->numberOfRawDataBlocks <= 0) {
} else {
const int bytesValid = *pBytesValid;
FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
if (hTp->numberOfRawDataBlocks > 0) {
hTp->globalFramePos += (bytesValid - *pBytesValid) * 8;
hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
}
}
}
@ -924,6 +929,11 @@ static TRANSPORTDEC_ERROR transportDec_readHeader(
}
}
}
/* if an error is detected terminate config parsing to avoid that an
* invalid config is accepted in the second pass */
if (err != TRANSPORTDEC_OK) {
break;
}
}
} else {
/* Reset CRC because the next bits are the beginning of a
@ -976,6 +986,9 @@ static TRANSPORTDEC_ERROR transportDec_readHeader(
CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
if (hTp->transportFmt == TT_MP4_LOAS) {
syncLayerFrameBits -= startPos - (INT)FDKgetValidBits(hBs) - (13);
if (syncLayerFrameBits <= 0) {
err = TRANSPORTDEC_SYNC_ERROR;
}
}
}
} else {
@ -1151,6 +1164,11 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
&rawDataBlockLength, &fTraverseMoreFrames,
&syncLayerFrameBits, &fConfigFound,
&headerBits);
if (headerBits > bitsAvail) {
err = (headerBits < (INT)hBs->hBitBuf.bufBits)
? TRANSPORTDEC_NOT_ENOUGH_BITS
: TRANSPORTDEC_SYNC_ERROR;
}
if (TPDEC_IS_FATAL_ERROR(err)) {
/* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
* next time. Ensure that the bit amount lands at a multiple of
@ -1181,8 +1199,6 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
}
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
/* Enforce reading of new data */
hTp->numberOfRawDataBlocks = 0;
break;
}
@ -1263,8 +1279,9 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS |
TPDEC_SYNCOK)) &&
err == TRANSPORTDEC_OK) {
err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
FDKgetValidBits(hBs) - syncLayerFrameBits);
err =
additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
(INT)FDKgetValidBits(hBs) - syncLayerFrameBits);
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
hTp->holdOffFrames++;
}
@ -1273,7 +1290,9 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
/* Rewind for retry because of not enough bits */
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
FDKpushBack(hBs, headerBits);
hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
headerBits = 0;
rawDataBlockLength = rawDataBlockLengthPrevious;
} else {
/* reset hold off frame counter */
hTp->holdOffFrames = 0;
@ -1460,7 +1479,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
for (i = 0; i < 2; i++) {
if (i > 0) {
FDKpushBack(hBs, bsStart - FDKgetValidBits(hBs));
FDKpushBack(hBs, bsStart - (INT)FDKgetValidBits(hBs));
configMode = AC_CM_ALLOC_MEM;
}
@ -1750,7 +1769,7 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info) {
info += i;
info->module_id = FDK_TPDEC;
#ifdef __ANDROID__
#ifdef SUPPRESS_BUILD_DATE_INFO
info->build_date = "";
info->build_time = "";
#else

View File

@ -647,7 +647,7 @@ TRANSPORTENC_ERROR transportEnc_GetLibInfo(LIB_INFO *info) {
info->module_id = FDK_TPENC;
info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
LIB_VERSION_STRING(info);
#ifdef __ANDROID__
#ifdef SUPPRESS_BUILD_DATE_INFO
info->build_date = "";
info->build_time = "";
#else

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -109,8 +109,6 @@ amm-info@iis.fraunhofer.de
#define TDL_ATTACK_DEFAULT_MS (15) /* default attack time in ms */
#define TDL_RELEASE_DEFAULT_MS (50) /* default release time in ms */
#define TDL_GAIN_SCALING (15) /* scaling of gain value. */
#ifdef __cplusplus
extern "C" {
#endif
@ -128,10 +126,7 @@ struct TDLimiter {
unsigned int maxBufIdx, delayBufIdx;
FIXP_DBL smoothState0;
FIXP_DBL minGain;
FIXP_DBL additionalGainPrev;
FIXP_DBL additionalGainFilterState;
FIXP_DBL additionalGainFilterState1;
INT scaling;
};
typedef enum {
@ -255,27 +250,16 @@ TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter,
/******************************************************************************
* pcmLimiter_Apply *
* limiter: limiter handle *
* pGain : pointer to gains to be applied to the signal before limiting, *
* which are downscaled by TDL_GAIN_SCALING bit. *
* These gains are delayed by gain_delay, and smoothed. *
* Smoothing is done by a butterworth lowpass filter with a cutoff *
* frequency which is fixed with respect to the sampling rate. *
* It is a substitute for the smoothing due to windowing and *
* overlap/add, if a gain is applied in frequency domain. *
* gain_scale: pointer to scaling exponents to be applied to the signal before *
* limiting, without delay and without smoothing *
* gain_size: number of elements in pGain, currently restricted to 1 *
* gain_delay: delay [samples] with which the gains in pGain shall be applied *
* gain_delay <= nSamples *
* samples: input/output buffer containing interleaved samples *
* precision of output will be DFRACT_BITS-TDL_GAIN_SCALING bits *
* nSamples: number of samples per channel *
* limiter: limiter handle *
* samplesIn: pointer to input buffer containing interleaved samples *
* samplesOut: pointer to output buffer containing interleaved samples *
* pGainPerSample: pointer to gains for each sample *
* scaling: scaling of output samples *
* nSamples: number of samples per channel *
* returns: error code *
******************************************************************************/
TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
INT_PCM* samplesOut, FIXP_DBL* pGain,
const INT* gain_scale, const UINT gain_size,
const UINT gain_delay, const UINT nSamples);
INT_PCM* samplesOut, FIXP_DBL* pGainPerSample,
const INT scaling, const UINT nSamples);
#endif /* #ifndef LIMITER_H */

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -152,7 +152,7 @@ TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs,
limiter->attack = attack;
limiter->attackConst = attackConst;
limiter->releaseConst = releaseConst;
limiter->threshold = threshold >> TDL_GAIN_SCALING;
limiter->threshold = threshold;
limiter->channels = maxChannels;
limiter->maxChannels = maxChannels;
limiter->sampleRate = maxSampleRate;
@ -165,18 +165,13 @@ TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs,
/* apply limiter */
TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
INT_PCM* samplesOut, FIXP_DBL* RESTRICT pGain,
const INT* RESTRICT gain_scale,
const UINT gain_size, const UINT gain_delay,
const UINT nSamples) {
INT_PCM* samplesOut, FIXP_DBL* pGainPerSample,
const INT scaling, const UINT nSamples) {
unsigned int i, j;
FIXP_DBL tmp1;
FIXP_DBL tmp2;
FIXP_DBL tmp, old, gain, additionalGain = 0, additionalGainUnfiltered;
FIXP_DBL tmp, old, gain, additionalGain = 0;
FIXP_DBL minGain = FL2FXCONST_DBL(1.0f / (1 << 1));
FDK_ASSERT(gain_size == 1);
FDK_ASSERT(gain_delay <= nSamples);
UINT additionalGainAvailable = 1;
if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
@ -185,7 +180,7 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
unsigned int attack = limiter->attack;
FIXP_DBL attackConst = limiter->attackConst;
FIXP_DBL releaseConst = limiter->releaseConst;
FIXP_DBL threshold = limiter->threshold;
FIXP_DBL threshold = limiter->threshold >> scaling;
FIXP_DBL max = limiter->max;
FIXP_DBL* maxBuf = limiter->maxBuf;
@ -195,55 +190,34 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
unsigned int delayBufIdx = limiter->delayBufIdx;
FIXP_DBL smoothState0 = limiter->smoothState0;
FIXP_DBL additionalGainSmoothState = limiter->additionalGainFilterState;
FIXP_DBL additionalGainSmoothState1 = limiter->additionalGainFilterState1;
if (!gain_delay) {
additionalGain = pGain[0];
if (gain_scale[0] > 0) {
additionalGain <<= gain_scale[0];
} else {
additionalGain >>= -gain_scale[0];
}
if (limiter->scaling != scaling) {
scaleValuesSaturate(delayBuf, attack * channels,
limiter->scaling - scaling);
scaleValuesSaturate(maxBuf, attack + 1, limiter->scaling - scaling);
max = scaleValueSaturate(max, limiter->scaling - scaling);
limiter->scaling = scaling;
}
if (pGainPerSample == NULL) {
additionalGainAvailable = 0;
}
for (i = 0; i < nSamples; i++) {
if (gain_delay) {
if (i < gain_delay) {
additionalGainUnfiltered = limiter->additionalGainPrev;
} else {
additionalGainUnfiltered = pGain[0];
}
/* Smooth additionalGain */
/* [b,a] = butter(1, 0.01) */
static const FIXP_SGL b[] = {FL2FXCONST_SGL(0.015466 * 2.0),
FL2FXCONST_SGL(0.015466 * 2.0)};
static const FIXP_SGL a[] = {(FIXP_SGL)MAXVAL_SGL,
FL2FXCONST_SGL(-0.96907)};
additionalGain = -fMult(additionalGainSmoothState, a[1]) +
fMultDiv2(additionalGainUnfiltered, b[0]) +
fMultDiv2(additionalGainSmoothState1, b[1]);
additionalGainSmoothState1 = additionalGainUnfiltered;
additionalGainSmoothState = additionalGain;
/* Apply the additional scaling that has no delay and no smoothing */
if (gain_scale[0] > 0) {
additionalGain <<= gain_scale[0];
} else {
additionalGain >>= -gain_scale[0];
}
}
/* get maximum absolute sample value of all channels, including the
* additional gain. */
tmp1 = (FIXP_DBL)0;
tmp = (FIXP_DBL)0;
for (j = 0; j < channels; j++) {
tmp2 = PCM_LIM2FIXP_DBL(samplesIn[j]);
tmp2 = fAbs(tmp2);
tmp2 = FIXP_DBL(INT(tmp2) ^ INT((tmp2 >> (SAMPLE_BITS_LIM - 1))));
tmp1 = fMax(tmp1, tmp2);
tmp2 =
(tmp2 == (FIXP_DBL)MINVAL_DBL) ? (FIXP_DBL)MAXVAL_DBL : fAbs(tmp2);
tmp = fMax(tmp, tmp2);
}
if (additionalGainAvailable) {
additionalGain = pGainPerSample[i];
tmp = fMult(tmp, additionalGain);
}
tmp = fMult(tmp1, additionalGain);
/* set threshold as lower border to save calculations in running maximum
* algorithm */
@ -314,22 +288,42 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
/* lookahead delay, apply gain */
for (j = 0; j < channels; j++) {
tmp = p_delayBuf[j];
p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
if (additionalGainAvailable) {
p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
} else {
p_delayBuf[j] = PCM_LIM2FIXP_DBL(samplesIn[j]);
}
/* Apply gain to delayed signal */
tmp = fMultDiv2(tmp, gain);
#if (SAMPLE_BITS == DFRACT_BITS)
samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM(
(FIXP_DBL)SATURATE_LEFT_SHIFT(tmp, scaling + 1, DFRACT_BITS));
#else
samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT(
tmp, TDL_GAIN_SCALING + 1, DFRACT_BITS));
tmp + ((FIXP_DBL)0x8000 >> (scaling + 1)), scaling + 1,
DFRACT_BITS));
#endif
}
gain >>= 1;
} else {
/* lookahead delay, apply gain=1.0f */
for (j = 0; j < channels; j++) {
tmp = p_delayBuf[j];
p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
if (additionalGainAvailable) {
p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
} else {
p_delayBuf[j] = PCM_LIM2FIXP_DBL(samplesIn[j]);
}
#if (SAMPLE_BITS == DFRACT_BITS)
samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM(
(FIXP_DBL)SATURATE_LEFT_SHIFT(tmp, scaling, DFRACT_BITS));
#else
samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT(
tmp, TDL_GAIN_SCALING, DFRACT_BITS));
tmp + ((FIXP_DBL)0x8000 >> scaling), scaling, DFRACT_BITS));
#endif
}
}
@ -354,13 +348,9 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
limiter->delayBufIdx = delayBufIdx;
limiter->smoothState0 = smoothState0;
limiter->additionalGainFilterState = additionalGainSmoothState;
limiter->additionalGainFilterState1 = additionalGainSmoothState1;
limiter->minGain = minGain;
limiter->additionalGainPrev = pGain[0];
return TDLIMIT_OK;
}
}
@ -370,7 +360,7 @@ TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter,
FIXP_DBL threshold) {
if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
limiter->threshold = threshold >> TDL_GAIN_SCALING;
limiter->threshold = threshold;
return TDLIMIT_OK;
}
@ -384,13 +374,7 @@ TDLIMITER_ERROR pcmLimiter_Reset(TDLimiterPtr limiter) {
limiter->cor = FL2FXCONST_DBL(1.0f / (1 << 1));
limiter->smoothState0 = FL2FXCONST_DBL(1.0f / (1 << 1));
limiter->minGain = FL2FXCONST_DBL(1.0f / (1 << 1));
limiter->additionalGainPrev =
FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING));
limiter->additionalGainFilterState =
FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING));
limiter->additionalGainFilterState1 =
FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING));
limiter->scaling = 0;
FDKmemset(limiter->maxBuf, 0, (limiter->attack + 1) * sizeof(FIXP_DBL));
FDKmemset(limiter->delayBuf, 0,

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -105,10 +105,10 @@ amm-info@iis.fraunhofer.de
/* library info */
#define PCMUTIL_LIB_VL0 3
#define PCMUTIL_LIB_VL1 0
#define PCMUTIL_LIB_VL1 1
#define PCMUTIL_LIB_VL2 0
#define PCMUTIL_LIB_TITLE "PCM Utility Lib"
#ifdef __ANDROID__
#ifdef SUPPRESS_BUILD_DATE_INFO
#define PCMUTIL_LIB_BUILD_DATE ""
#define PCMUTIL_LIB_BUILD_TIME ""
#else

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -252,7 +252,7 @@ typedef enum {
scenario. Default parameter value is 3 frames. */
} SACDEC_PARAM;
#define PCM_MPS INT_PCM
#define PCM_MPS LONG
/**
* \brief MPEG Surround decoder handle.
@ -401,17 +401,22 @@ int mpegSurroundDecoder_Parse(CMpegSurroundDecoder *pMpegSurroundDecoder,
* for each output audio channel is stored into.
* \param mapDescr Channep map descriptor for output channel mapping
* to be used (From MPEG PCE ordering to whatever is required).
* \param inDataHeadroom Headroom of SAC input time signal to prevent
* clipping.
* \param outDataHeadroom Pointer to headroom of SAC output time signal to
* prevent clipping.
*
* \return Error code.
*/
int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
INT_PCM *input, PCM_MPS *pTimeData,
PCM_MPS *input, PCM_MPS *pTimeData,
const int timeDataSize, int timeDataFrameSize,
int *nChannels, int *frameSize, int sampleRate,
AUDIO_OBJECT_TYPE coreCodec,
AUDIO_CHANNEL_TYPE channelType[],
UCHAR channelIndices[],
const FDK_channelMapDescr *const mapDescr);
const FDK_channelMapDescr *const mapDescr,
const INT inDataHeadroom, INT *outDataHeadroom);
/**
* \brief Deallocate a MPEG Surround decoder instance.

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -1555,22 +1555,20 @@ static SACDEC_ERROR mapIndexData(
/* Interpolate */
i1 = 0;
for (i = 0; i < numParameterSets; i++) {
int xi, i2, x1, x2;
if (aInterpolate[i] != 1) {
i1 = i;
}
i2 = i;
while (aInterpolate[i2] == 1) {
i2++;
if (i2 >= MAX_PARAMETER_SETS) return MPS_WRONG_PARAMETERSETS;
}
x1 = paramSlot[i1];
xi = paramSlot[i];
x2 = paramSlot[i2];
} else {
int xi, i2, x1, x2;
if (aInterpolate[i] == 1) {
for (i2 = i; i2 < numParameterSets; i2++) {
if (aInterpolate[i2] != 1) break;
}
if (i2 >= numParameterSets) return MPS_WRONG_PARAMETERSETS;
x1 = paramSlot[i1];
xi = paramSlot[i];
x2 = paramSlot[i2];
for (band = startBand; band < stopBand; band++) {
int yi, y1, y2;
y1 = outputIdxData[xttIdx][i1][band];
@ -1589,9 +1587,9 @@ static SACDEC_ERROR mapIndexData(
for (ps = 0; ps < numParameterSets; ps++) {
if (quantMode && (paramType == t_CLD)) {
if (pOttVsTotDbIn == 0) return MPS_WRONG_OTT;
if ((pOttVsTotDb1 == 0) && (ottVsTotDbMode == ottVsTotDb1Activ))
if ((pOttVsTotDb1 == 0) && (ottVsTotDbMode & ottVsTotDb1Activ))
return MPS_WRONG_OTT;
if ((pOttVsTotDb2 == 0) && (ottVsTotDbMode == ottVsTotDb2Activ))
if ((pOttVsTotDb2 == 0) && (ottVsTotDbMode & ottVsTotDb2Activ))
return MPS_WRONG_OTT;
for (pb = startBand; pb < stopBand; pb++) {
@ -1613,6 +1611,10 @@ static SACDEC_ERROR mapIndexData(
} /* for( i = 0 ; i < numParameterSets; i++ ) */
if (extendFrame) {
if (paramType == t_IPD) {
llData->bsQuantCoarseXXX[numParameterSets] =
llData->bsQuantCoarseXXX[numParameterSets - 1];
}
for (band = startBand; band < stopBand; band++) {
outputDataIdx[xttIdx][numParameterSets][band] =
outputDataIdx[xttIdx][numParameterSets - 1][band];

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -117,6 +117,9 @@ amm-info@iis.fraunhofer.de
/* Scaling of spectral data after applying M2 matrix, but only for binaural
upmix type Scaling is compensated later in synthesis qmf filterbank */
#define SCALE_DATA_APPLY_M2 (1)
/* Applying M2 parameter in combination with phase coding needs 2 bits headroom
* because up to a maximum of 4 spectral values can be added for USAC */
#define SCALE_DATA_APPLY_M2_PC (2)
SACDEC_ERROR initM1andM2(spatialDec* self, int initStatesFlag,
int configChanged);

View File

@ -766,7 +766,7 @@ SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
/* output scaling */
for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) {
int outputScale = 0, outputGain_e = 0, scale = 0;
int outputScale = 0, outputGain_e = 0, scale = -(8) + (1);
FIXP_DBL outputGain_m = getChGain(self, nCh, &outputGain_e);
if (!isTwoChMode(self->upmixType) && !bypassMode) {
@ -775,7 +775,7 @@ SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
synthesis qmf */
}
scale = outputScale;
scale += outputScale;
qmfChangeOutScalefactor(&self->pQmfDomain->QmfDomainOut[nCh].fb, scale);
qmfChangeOutGain(&self->pQmfDomain->QmfDomainOut[nCh].fb, outputGain_m,
@ -1223,18 +1223,24 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
!(self->stereoConfigIndex == 3)) {
for (i = 0; i < self->qmfBands; i++) {
self_qmfResidualReal__FDK_0_0[i] =
fMult(self_qmfResidualReal__FDK_0_0[i] << 1,
fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i],
1 + self->sacInDataHeadroom - (1)),
self->clipProtectGain__FDK);
self_qmfResidualImag__FDK_0_0[i] =
fMult(self_qmfResidualImag__FDK_0_0[i] << 1,
fMult(scaleValueSaturate(self_qmfResidualImag__FDK_0_0[i],
1 + self->sacInDataHeadroom - (1)),
self->clipProtectGain__FDK);
}
} else {
for (i = 0; i < self->qmfBands; i++) {
self_qmfResidualReal__FDK_0_0[i] = fMult(
self_qmfResidualReal__FDK_0_0[i], self->clipProtectGain__FDK);
self_qmfResidualImag__FDK_0_0[i] = fMult(
self_qmfResidualImag__FDK_0_0[i], self->clipProtectGain__FDK);
self_qmfResidualReal__FDK_0_0[i] =
fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i],
self->sacInDataHeadroom - (1)),
self->clipProtectGain__FDK);
self_qmfResidualImag__FDK_0_0[i] =
fMult(scaleValueSaturate(self_qmfResidualImag__FDK_0_0[i],
self->sacInDataHeadroom - (1)),
self->clipProtectGain__FDK);
}
}
}
@ -1317,10 +1323,12 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
if ((self->tempShapeConfig == 1) && (!isTwoChMode(self->upmixType))) {
for (ch = 0; ch < self->numOutputChannels; ch++) {
for (hyb = 0; hyb < self->tp_hybBandBorder; hyb++) {
self->hybOutputRealDry__FDK[ch][hyb] +=
self->hybOutputRealWet__FDK[ch][hyb];
self->hybOutputImagDry__FDK[ch][hyb] +=
self->hybOutputImagWet__FDK[ch][hyb];
self->hybOutputRealDry__FDK[ch][hyb] =
fAddSaturate(self->hybOutputRealDry__FDK[ch][hyb],
self->hybOutputRealWet__FDK[ch][hyb]);
self->hybOutputImagDry__FDK[ch][hyb] =
fAddSaturate(self->hybOutputImagDry__FDK[ch][hyb],
self->hybOutputImagWet__FDK[ch][hyb]);
} /* loop hyb */
} /* loop ch */
err = subbandTPApply(
@ -1341,11 +1349,11 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
FIXP_DBL *RESTRICT pRealWet = self->hybOutputRealWet__FDK[ch];
FIXP_DBL *RESTRICT pImagWet = self->hybOutputImagWet__FDK[ch];
for (hyb = 0; hyb < nHybBands; hyb++) {
pRealDry[hyb] += pRealWet[hyb];
pImagDry[hyb] += pImagWet[hyb];
pRealDry[hyb] = fAddSaturate(pRealDry[hyb], pRealWet[hyb]);
pImagDry[hyb] = fAddSaturate(pImagDry[hyb], pImagWet[hyb]);
} /* loop hyb */
for (; hyb < self->hybridBands; hyb++) {
pRealDry[hyb] += pRealWet[hyb];
pRealDry[hyb] = fAddSaturate(pRealDry[hyb], pRealWet[hyb]);
} /* loop hyb */
} /* loop ch */
} /* ( self->tempShapeConfig == 1 ) || ( self->tempShapeConfig == 2 ) */
@ -1414,6 +1422,7 @@ SACDEC_ERROR SpatialDecApplyFrame(
FDK_ASSERT(self != NULL);
FDK_ASSERT(pControlFlags != NULL);
FDK_ASSERT(pcmOutBuf != NULL);
FDK_ASSERT(self->sacInDataHeadroom >= (1));
self->errInt = err; /* Init internal error */

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -523,6 +523,9 @@ struct spatialDec_struct {
new frame after SSC change (aka
decodeAfterConfigHasChangedFlag). */
SpatialDecConcealmentInfo concealInfo;
INT sacInDataHeadroom; /* Headroom of the SAC input time signal to prevent
clipping */
};
#define SACDEC_SYNTAX_MPS 1

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -249,10 +249,10 @@ typedef struct {
} MEM_REQUIREMENTS;
#define PCM_MPS INT_PCM
#define PCM_MPSF FIXP_PCM
#define PCM_MPS LONG
#define PCM_MPSF FIXP_DBL
#define FIXP_DBL2PCM_MPS(x) ((INT_PCM)FX_DBL2FX_PCM(x))
#define FIXP_DBL2PCM_MPS(x) ((LONG)(x))
/* exposed functions (library interface) */

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -1507,15 +1507,17 @@ bail:
}
int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
INT_PCM *input, PCM_MPS *pTimeData,
PCM_MPS *input, PCM_MPS *pTimeData,
const int timeDataSize, int timeDataFrameSize,
int *nChannels, int *frameSize, int sampleRate,
AUDIO_OBJECT_TYPE coreCodec,
AUDIO_CHANNEL_TYPE channelType[],
UCHAR channelIndices[],
const FDK_channelMapDescr *const mapDescr) {
const FDK_channelMapDescr *const mapDescr,
const INT inDataHeadroom, INT *outDataHeadroom) {
SACDEC_ERROR err = MPS_OK;
PCM_MPS *pTimeOut = pTimeData;
PCM_MPS *TDinput = NULL;
UINT initControlFlags = 0, controlFlags = 0;
int timeDataRequiredSize = 0;
int newData;
@ -1534,6 +1536,9 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
return MPS_NOTOK;
}
pMpegSurroundDecoder->pSpatialDec->sacInDataHeadroom = inDataHeadroom;
*outDataHeadroom = (INT)(8);
pMpegSurroundDecoder->pSpatialDec->pConfigCurrent =
&pMpegSurroundDecoder
->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
@ -1682,8 +1687,7 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
(timeDataFrameSize *
pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsSynthesis) /
pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis;
pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput =
pTimeData + timeDataFrameSizeOut - timeDataFrameSize;
TDinput = pTimeData + timeDataFrameSizeOut - timeDataFrameSize;
for (int i = *nChannels - 1; i >= 0; i--) {
FDKmemmove(pTimeData + (i + 1) * timeDataFrameSizeOut - timeDataFrameSize,
pTimeData + timeDataFrameSize * i,
@ -1694,8 +1698,8 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
} else {
if (pMpegSurroundDecoder->mpegSurroundUseTimeInterface) {
FDKmemcpy(input, pTimeData,
sizeof(INT_PCM) * (*nChannels) * (*frameSize));
pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput = input;
sizeof(PCM_MPS) * (*nChannels) * (*frameSize));
TDinput = input;
}
}
@ -1707,8 +1711,8 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
&pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode],
pMpegSurroundDecoder->mpegSurroundUseTimeInterface ? INPUTMODE_TIME
: INPUTMODE_QMF_SBR,
pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput, NULL, NULL,
pTimeOut, *frameSize, &controlFlags, *nChannels, mapDescr);
TDinput, NULL, NULL, pTimeOut, *frameSize, &controlFlags, *nChannels,
mapDescr);
*nChannels = pMpegSurroundDecoder->pSpatialDec->numOutputChannelsAT;
if (err !=
@ -1781,7 +1785,7 @@ void mpegSurroundDecoder_Close(CMpegSurroundDecoder *pMpegSurroundDecoder) {
}
#define SACDEC_VL0 2
#define SACDEC_VL1 0
#define SACDEC_VL1 1
#define SACDEC_VL2 0
int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) {
@ -1800,7 +1804,7 @@ int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) {
info += i;
info->module_id = FDK_MPSDEC;
#ifdef __ANDROID__
#ifdef SUPPRESS_BUILD_DATE_INFO
info->build_date = "";
info->build_time = "";
#else

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -113,6 +113,8 @@ amm-info@iis.fraunhofer.de
#include "FDK_trigFcts.h"
#include "FDK_decorrelate.h"
#define SAC_DEC_APPLY_M2_SCALE(spec, s) ((spec) >> (-(s)))
/**
* \brief Linear interpolation between two parameter values.
* a*alpha + b*(1-alpha)
@ -185,8 +187,12 @@ SACDEC_ERROR SpatialDecQMFAnalysis(spatialDec *self, const PCM_MPS *inData,
if (!isTwoChMode(self->upmixType) && !bypassMode) {
int i;
for (i = 0; i < self->qmfBands; i++) {
qmfReal[ch][i] = fMult(qmfReal[ch][i], self->clipProtectGain__FDK);
qmfImag[ch][i] = fMult(qmfImag[ch][i], self->clipProtectGain__FDK);
qmfReal[ch][i] = fMult(
scaleValueSaturate(qmfReal[ch][i], self->sacInDataHeadroom - (1)),
self->clipProtectGain__FDK);
qmfImag[ch][i] = fMult(
scaleValueSaturate(qmfImag[ch][i], self->sacInDataHeadroom - (1)),
self->clipProtectGain__FDK);
}
}
}
@ -214,16 +220,17 @@ SACDEC_ERROR SpatialDecFeedQMF(spatialDec *self, FIXP_DBL **qmfInDataReal,
/* Write Input data to pQmfRealAnalysis. */
if (self->bShareDelayWithSBR) {
FDK_QmfDomain_GetSlot(
&self->pQmfDomain->QmfDomainIn[ch], ts + HYBRID_FILTER_DELAY, 0,
MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis, pQmfImagAnalysis, 15);
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch],
ts + HYBRID_FILTER_DELAY, 0,
MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis,
pQmfImagAnalysis, 15 + (1));
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts,
MAX_QMF_BANDS_TO_HYBRID, self->qmfBands,
pQmfRealAnalysis, pQmfImagAnalysis, 15);
pQmfRealAnalysis, pQmfImagAnalysis, 15 + (1));
} else {
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts, 0,
self->qmfBands, pQmfRealAnalysis,
pQmfImagAnalysis, 15);
pQmfImagAnalysis, 15 + (1));
}
if (ts == self->pQmfDomain->globalConf.nQmfTimeSlots - 1) {
/* Is currently also needed in case we dont have any overlap. We need to
@ -499,8 +506,8 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
for (pb = 0, qs = 3; pb < 2; pb++) {
INT s;
FIXP_DBL maxVal;
FIXP_SGL mReal1;
FIXP_SGL mReal0, mImag0;
FIXP_DBL mReal1;
FIXP_DBL mReal0, mImag0;
FIXP_DBL iReal0, iImag0, iReal1;
iReal0 = interpolateParameter(alpha, MReal0[pb], MRealPrev0[pb]);
@ -513,9 +520,9 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
s = fMax(CntLeadingZeros(maxVal) - 1, 0);
s = fMin(s, scale_param_m2);
mReal0 = FX_DBL2FX_SGL(iReal0 << s);
mImag0 = FX_DBL2FX_SGL(iImag0 << s);
mReal1 = FX_DBL2FX_SGL(iReal1 << s);
mReal0 = iReal0 << s;
mImag0 = iImag0 << s;
mReal1 = iReal1 << s;
s = scale_param_m2 - s;
@ -634,8 +641,7 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
}
if (self->phaseCoding == 3) {
/* + SCALE_DATA_APPLY_M2 to compensate for Div2 below ?! */
scale_param_m2 = SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2;
scale_param_m2 = -(SCALE_DATA_APPLY_M2_PC - 1);
}
for (row = 0; row < self->numM2rows; row++) {
@ -686,10 +692,10 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
} else { /* isBinauralMode(self->upmixType) */
for (qs = 0; qs < complexHybBands; qs++) {
pHybOutRealDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
<< (scale_param_m2);
pHybOutImagDry[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
<< (scale_param_m2);
pHybOutRealDry[qs] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
}
M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col],
@ -697,27 +703,27 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
self->kernels_width, alpha, complexParBands);
/* direct signals sign is -1 for qs = 0,2 */
pHybOutRealDry[0] += fMultDiv2(pWImag[0], pKernel[0])
<< (scale_param_m2);
pHybOutImagDry[0] -= fMultDiv2(pWReal[0], pKernel[0])
<< (scale_param_m2);
pHybOutRealDry[0] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
pHybOutImagDry[0] -= SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
pHybOutRealDry[2] += fMultDiv2(pWImag[2], pKernel[2])
<< (scale_param_m2);
pHybOutImagDry[2] -= fMultDiv2(pWReal[2], pKernel[2])
<< (scale_param_m2);
pHybOutRealDry[2] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
pHybOutImagDry[2] -= SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
/* direct signals sign is +1 for qs = 1,3,4,5,...,complexHybBands */
pHybOutRealDry[1] -= fMultDiv2(pWImag[1], pKernel[1])
<< (scale_param_m2);
pHybOutImagDry[1] += fMultDiv2(pWReal[1], pKernel[1])
<< (scale_param_m2);
pHybOutRealDry[1] -= SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
pHybOutImagDry[1] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
for (qs = 3; qs < complexHybBands; qs++) {
pHybOutRealDry[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
<< (scale_param_m2);
pHybOutImagDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
<< (scale_param_m2);
pHybOutRealDry[qs] -= SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
}
} /* self->upmixType */
} /* if (activParamBands) */
@ -770,17 +776,17 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
FIXP_DBL *RESTRICT pHybOutImag;
for (qs = 0; qs < resHybIndex; qs++) {
pHybOutRealDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
<< (scale_param_m2);
pHybOutImagDry[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
<< (scale_param_m2);
pHybOutRealDry[qs] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
}
/* decor signals */
for (; qs < complexHybBands; qs++) {
pHybOutRealWet[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
<< (scale_param_m2);
pHybOutImagWet[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
<< (scale_param_m2);
pHybOutRealWet[qs] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
pHybOutImagWet[qs] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
}
M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col],
@ -790,20 +796,20 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
/* direct signals sign is -1 for qs = 0,2 */
/* direct signals sign is +1 for qs = 1,3.. */
if (toolsDisabled) {
pHybOutRealDry[0] += fMultDiv2(pWImag[0], pKernel[0])
<< (scale_param_m2);
pHybOutImagDry[0] -= fMultDiv2(pWReal[0], pKernel[0])
<< (scale_param_m2);
pHybOutRealDry[0] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
pHybOutImagDry[0] -= SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
pHybOutRealDry[1] -= fMultDiv2(pWImag[1], pKernel[1])
<< (scale_param_m2);
pHybOutImagDry[1] += fMultDiv2(pWReal[1], pKernel[1])
<< (scale_param_m2);
pHybOutRealDry[1] -= SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
pHybOutImagDry[1] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
pHybOutRealDry[2] += fMultDiv2(pWImag[2], pKernel[2])
<< (scale_param_m2);
pHybOutImagDry[2] -= fMultDiv2(pWReal[2], pKernel[2])
<< (scale_param_m2);
pHybOutRealDry[2] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
pHybOutImagDry[2] -= SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
} else {
pHybOutReal = &pHybOutRealDry[0];
pHybOutImag = &pHybOutImagDry[0];
@ -811,46 +817,60 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
pHybOutReal = &pHybOutRealWet[0];
pHybOutImag = &pHybOutImagWet[0];
}
pHybOutReal[0] += fMultDiv2(pWImag[0], pKernel[0])
<< (scale_param_m2);
pHybOutImag[0] -= fMultDiv2(pWReal[0], pKernel[0])
<< (scale_param_m2);
pHybOutReal[0] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
pHybOutImag[0] -= SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
if (1 == resHybIndex) {
pHybOutReal = &pHybOutRealWet[0];
pHybOutImag = &pHybOutImagWet[0];
}
pHybOutReal[1] -= fMultDiv2(pWImag[1], pKernel[1])
<< (scale_param_m2);
pHybOutImag[1] += fMultDiv2(pWReal[1], pKernel[1])
<< (scale_param_m2);
pHybOutReal[1] -= SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
pHybOutImag[1] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
if (2 == resHybIndex) {
pHybOutReal = &pHybOutRealWet[0];
pHybOutImag = &pHybOutImagWet[0];
}
pHybOutReal[2] += fMultDiv2(pWImag[2], pKernel[2])
<< (scale_param_m2);
pHybOutImag[2] -= fMultDiv2(pWReal[2], pKernel[2])
<< (scale_param_m2);
pHybOutReal[2] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
pHybOutImag[2] -= SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
}
for (qs = 3; qs < resHybIndex; qs++) {
pHybOutRealDry[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
<< (scale_param_m2);
pHybOutImagDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
<< (scale_param_m2);
pHybOutRealDry[qs] -= SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
}
/* decor signals */
for (; qs < complexHybBands; qs++) {
pHybOutRealWet[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
<< (scale_param_m2);
pHybOutImagWet[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
<< (scale_param_m2);
pHybOutRealWet[qs] -= SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
pHybOutImagWet[qs] += SAC_DEC_APPLY_M2_SCALE(
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
}
} /* self->upmixType */
} /* if (activParamBands) { */
} /* self->numVChannels */
if (self->phaseCoding == 3) {
scaleValuesSaturate(pHybOutRealDry, complexHybBands,
SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
scaleValuesSaturate(pHybOutImagDry, complexHybBands,
SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
if (!toolsDisabled) {
scaleValuesSaturate(pHybOutRealWet, complexHybBands,
SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
scaleValuesSaturate(pHybOutImagWet, complexHybBands,
SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
}
}
}
C_ALLOC_SCRATCH_END(pKernel, FIXP_SGL, MAX_HYBRID_BANDS);
@ -919,6 +939,7 @@ SACDEC_ERROR SpatialDecSynthesis(spatialDec *self, const INT ts,
self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -=
self->clipProtectGainSF__FDK;
self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -= (1);
} else {
/* Call the QMF synthesis for dry. */
err = CalculateSpaceSynthesisQmf(&self->pQmfDomain->QmfDomainOut[outCh],

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de
SACDEC_ERROR CalculateSpaceSynthesisQmf(
const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr,
const FIXP_DBL *Si, const INT stride, INT_PCM *timeSig) {
const FIXP_DBL *Si, const INT stride, PCM_MPS *timeSig) {
SACDEC_ERROR err = MPS_OK;
if (hQmfDomainOutCh == NULL) {

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -124,7 +124,7 @@ amm-info@iis.fraunhofer.de
*/
SACDEC_ERROR CalculateSpaceSynthesisQmf(
const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr,
const FIXP_DBL *Si, const INT stride, INT_PCM *timeSig);
const FIXP_DBL *Si, const INT stride, PCM_MPS *timeSig);
/**
* \brief Convert audio input data to qmf representation.

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -162,75 +162,59 @@ static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
FIXP_DBL nrg;
/* qs = 12, 13, 14 */
slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 15 */
slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 16, 17 */
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
slotNrg[4] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
slotNrg[4] =
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 18, 19, 20 */
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
slotNrg[5] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
slotNrg[5] =
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 21, 22 */
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
slotNrg[6] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
slotNrg[6] =
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 23, 24 */
if (hybBands > 23) {
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 25, 26, 29, 28, 29 */
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
slotNrg[7] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
slotNrg[7] =
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 30 ... min(41,hybBands-1) */
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
for (qs = 31; qs < hybBands; qs++) {
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
fPow2Div2((*pImag++) << maxValSF)) >>
(SF_FACTOR_SLOT - 1));
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
}
slotNrg[8] = nrg;
} else {
@ -239,49 +223,22 @@ static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
}
}
static inline INT getMaxValDmx(FIXP_DBL *RESTRICT pReal,
FIXP_DBL *RESTRICT pImag, INT cplxBands,
INT hybBands) {
INT qs, clz;
FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
static inline void combineDryWet(FIXP_DBL *RESTRICT pReal,
FIXP_DBL *RESTRICT pImag,
FIXP_DBL *RESTRICT pHybOutputRealDry,
FIXP_DBL *RESTRICT pHybOutputImagDry,
FIXP_DBL *RESTRICT pHybOutputRealWet,
FIXP_DBL *RESTRICT pHybOutputImagWet,
INT cplxBands, INT hybBands) {
INT qs;
for (qs = 12; qs < cplxBands; qs++) {
maxVal |= fAbs(pReal[qs]);
maxVal |= fAbs(pImag[qs]);
pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
pImag[qs] = (pHybOutputImagDry[qs] >> 1) + (pHybOutputImagWet[qs] >> 1);
}
for (; qs < hybBands; qs++) {
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,
@ -296,17 +253,17 @@ static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry,
dry = wet = FL2FXCONST_DBL(0.0f);
for (qs = 0; qs < cplxBands; qs++) {
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]) +
fPow2Div2(pHybOutputImagDry[qs]));
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]) +
fPow2Div2(pHybOutputImagWet[qs]));
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)) +
fPow2Div2(pHybOutputImagDry[qs] << (1)));
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)) +
fPow2Div2(pHybOutputImagWet[qs] << (1)));
}
for (; qs < hybBands; qs++) {
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]));
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]));
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)));
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)));
}
*slotAmp_dry = dry;
*slotAmp_wet = wet;
*slotAmp_dry = dry >> (2 * (1));
*slotAmp_wet = wet >> (2 * (1));
}
#if defined(__aarch64__)
@ -327,11 +284,14 @@ shapeBBEnv(FIXP_DBL *pHybOutputRealDry, FIXP_DBL *pHybOutputImagDry,
}
} else {
for (qs = 0; qs < cplxBands; qs++) {
pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale;
pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac) << scale;
pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
pHybOutputImagDry[qs] = SATURATE_LEFT_SHIFT(
fMultDiv2(pHybOutputImagDry[qs], dryFac), scale, DFRACT_BITS);
}
for (; qs < hybBands; qs++) {
pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale;
pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
}
}
}
@ -367,7 +327,7 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
INT shapeActiv = 1;
INT hybBands = fixMin(42, self->hybridBands);
INT staticScale = self->staticDecScale;
INT staticScale = self->staticDecScale + (1);
INT cplxBands;
cplxBands = fixMin(42, self->hybridBands);
@ -386,15 +346,18 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
prevChOffs = ch;
pReal = pScratchBuffer;
pImag = pScratchBuffer + 42;
clz = getMaxValDryWet(
pReal, pImag, self->hybOutputRealDry__FDK[ch],
self->hybOutputImagDry__FDK[ch], self->hybOutputRealWet__FDK[ch],
self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
combineDryWet(pReal, pImag, self->hybOutputRealDry__FDK[ch],
self->hybOutputImagDry__FDK[ch],
self->hybOutputRealWet__FDK[ch],
self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
} else {
prevChOffs = ch + self->numOutputChannels;
pReal = self->hybInputReal__FDK[ch];
pImag = self->hybInputImag__FDK[ch];
clz = getMaxValDmx(pReal, pImag, cplxBands, hybBands);
clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
}
partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs];
@ -411,8 +374,10 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
SF_FACTOR_SLOT */
}
slotNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT;
frameNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT;
slotNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
SF_FACTOR_SLOT;
frameNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
SF_FACTOR_SLOT;
partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1);
@ -652,14 +617,16 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
fixMax(3, fixMax(dryFacSF, slotAmpSF)); /* scale is at least with 3
bits to avoid overflows
when calculating dryFac */
dryFac = dryFac >> (scale - dryFacSF);
slotAmp_ratio = slotAmp_ratio >> (scale - slotAmpSF);
dryFac = dryFac >> fixMin(scale - dryFacSF, DFRACT_BITS - 1);
slotAmp_ratio =
slotAmp_ratio >> fixMin(scale - slotAmpSF, DFRACT_BITS - 1);
/* limit dryFac */
dryFac = fixMax(
FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1),
fMult(dryFac, slotAmp_ratio) - (slotAmp_ratio >> scale) +
(dryFac >> scale));
fMult(dryFac, slotAmp_ratio) -
(slotAmp_ratio >> fixMin(scale, DFRACT_BITS - 1)) +
(dryFac >> fixMin(scale, DFRACT_BITS - 1)));
dryFac = fixMin(
FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1),
dryFac); /* reduce shift bits by 3, because upper
@ -673,8 +640,8 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
/* shaping */
shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6],
&self->hybOutputImagDry__FDK[ch][6], dryFac, scale, cplxBands,
hybBands);
&self->hybOutputImagDry__FDK[ch][6], dryFac,
fixMin(scale, DFRACT_BITS - 1), cplxBands, hybBands);
}
}
}

View File

@ -111,21 +111,12 @@ amm-info@iis.fraunhofer.de
#include "machine_type.h"
/* Global ROM table data type: */
#ifndef ARCH_PREFER_MULT_32x32
#define FIXP_CFG FIXP_SGL
#define FX_CFG2FX_DBL FX_SGL2FX_DBL
#define FX_CFG2FX_SGL
#define CFG(a) (FX_DBL2FXCONST_SGL(a))
#define FL2FXCONST_CFG FL2FXCONST_SGL
#define FX_DBL2FX_CFG(x) FX_DBL2FX_SGL((FIXP_DBL)(x))
#else
#define FIXP_CFG FIXP_DBL
#define FX_CFG2FX_DBL
#define FX_CFG2FX_SGL FX_DBL2FX_SGL
#define CFG(a) FIXP_DBL(a)
#define FL2FXCONST_CFG FL2FXCONST_DBL
#define FX_DBL2FX_CFG(x) ((FIXP_DBL)(x))
#endif
/* others */
#define SCALE_INV_ICC (2)
@ -133,15 +124,9 @@ amm-info@iis.fraunhofer.de
#define QCC_SCALE 1
#define M1M2_DATA FIXP_DBL
#ifndef ARCH_PREFER_MULT_32x32
#define M1M2_CDATA FIXP_SGL
#define M1M2_CDATA2FX_DBL(a) FX_SGL2FX_DBL(a)
#define FX_DBL2M1M2_CDATA(a) FX_DBL2FX_SGL(a)
#else
#define M1M2_CDATA FIXP_DBL
#define M1M2_CDATA2FX_DBL(a) (a)
#define FX_DBL2M1M2_CDATA(a) (a)
#endif
#define CLIP_PROTECT_GAIN_0(x) FL2FXCONST_CFG(((x) / (float)(1 << 0)))
#define CLIP_PROTECT_GAIN_1(x) FL2FXCONST_CFG(((x) / (float)(1 << 1)))

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -106,6 +106,8 @@ amm-info@iis.fraunhofer.de
#include "FDK_matrixCalloc.h"
#include "sac_rom.h"
#define SF_FREQ_DOMAIN_HEADROOM (2 * (1))
#define BP_GF_START 6
#define BP_GF_SIZE 25
#define HP_SIZE 9
@ -114,6 +116,16 @@ amm-info@iis.fraunhofer.de
#define SF_WET 5
#define SF_DRY \
3 /* SF_DRY == 2 would produce good conformance test results as well */
#define SF_DRY_NRG \
(4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
calculation needs 4 bits headroom, headroom can be reduced by 1 \
bit due to fPow2Div2() usage */
#define SF_WET_NRG \
(4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
calculation needs 4 bits headroom, headroom can be reduced by 1 \
bit due to fPow2Div2() usage */
#define SF_PRODUCT_BP_GF 13
#define SF_PRODUCT_BP_GF_GF 26
#define SF_SCALE 2
@ -172,18 +184,6 @@ amm-info@iis.fraunhofer.de
STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO)
*/
#define DRY_ENER_WEIGHT(DryEner) DryEner = DryEner >> dry_scale_dmx
#define WET_ENER_WEIGHT(WetEner) WetEner = WetEner << wet_scale_dmx
#define DRY_ENER_SUM_REAL(DryEner, dmxReal, n) \
DryEner += \
fMultDiv2(fPow2Div2(dmxReal << SF_DRY), pBP[n]) >> ((2 * SF_DRY) - 2)
#define DRY_ENER_SUM_CPLX(DryEner, dmxReal, dmxImag, n) \
DryEner += fMultDiv2( \
fPow2Div2(dmxReal << SF_DRY) + fPow2Div2(dmxImag << SF_DRY), pBP[n])
#define CALC_WET_SCALE(dryIdx, wetIdx) \
if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \
scale[wetIdx] = STP_SCALE_LIMIT_HI; \
@ -206,29 +206,6 @@ struct STP_DEC {
int update_old_ener;
};
inline void combineSignalReal(FIXP_DBL *hybOutputRealDry,
FIXP_DBL *hybOutputRealWet, int bands) {
int n;
for (n = bands - 1; n >= 0; n--) {
*hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet;
hybOutputRealDry++, hybOutputRealWet++;
}
}
inline void combineSignalRealScale1(FIXP_DBL *hybOutputRealDry,
FIXP_DBL *hybOutputRealWet, FIXP_DBL scaleX,
int bands) {
int n;
for (n = bands - 1; n >= 0; n--) {
*hybOutputRealDry =
*hybOutputRealDry +
(fMultDiv2(*hybOutputRealWet, scaleX) << (SF_SCALE + 1));
hybOutputRealDry++, hybOutputRealWet++;
}
}
inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
FIXP_DBL *hybOutputImagDry,
FIXP_DBL *hybOutputRealWet,
@ -236,8 +213,8 @@ inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
int n;
for (n = bands - 1; n >= 0; n--) {
*hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet;
*hybOutputImagDry = *hybOutputImagDry + *hybOutputImagWet;
*hybOutputRealDry = fAddSaturate(*hybOutputRealDry, *hybOutputRealWet);
*hybOutputImagDry = fAddSaturate(*hybOutputImagDry, *hybOutputImagWet);
hybOutputRealDry++, hybOutputRealWet++;
hybOutputImagDry++, hybOutputImagWet++;
}
@ -253,12 +230,14 @@ inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry,
FIXP_DBL scaleY;
for (n = bands - 1; n >= 0; n--) {
scaleY = fMultDiv2(scaleX, *pBP);
*hybOutputRealDry =
*hybOutputRealDry +
(fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 2));
*hybOutputImagDry =
*hybOutputImagDry +
(fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 2));
*hybOutputRealDry = SATURATE_LEFT_SHIFT(
(*hybOutputRealDry >> 1) +
(fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 1)),
1, DFRACT_BITS);
*hybOutputImagDry = SATURATE_LEFT_SHIFT(
(*hybOutputImagDry >> 1) +
(fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 1)),
1, DFRACT_BITS);
hybOutputRealDry++, hybOutputRealWet++;
hybOutputImagDry++, hybOutputImagWet++;
pBP++;
@ -305,12 +284,10 @@ SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) {
for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE));
self->oldWetEnerLD64[ch] =
FL2FXCONST_DBL(0.34375f); /* 32768.0*32768.0/2^(44-26-10) */
self->oldWetEnerLD64[ch] = FL2FXCONST_DBL(0.0);
}
for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) {
self->oldDryEnerLD64[ch] =
FL2FXCONST_DBL(0.1875f); /* 32768.0*32768.0/2^(44-26) */
self->oldDryEnerLD64[ch] = FL2FXCONST_DBL(0.0);
}
self->BP = BP__FDK;
@ -364,7 +341,12 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
{
cplxBands = BP_GF_SIZE;
cplxHybBands = self->hybridBands;
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;
}
@ -390,8 +372,12 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK);
}
for (ch = 0; ch < self->numOutputChannels; ch++) {
hStpDec->oldWetEnerLD64[ch] =
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK);
if (self->treeConfig == TREE_212)
hStpDec->oldWetEnerLD64[ch] =
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR__FDK);
else
hStpDec->oldWetEnerLD64[ch] =
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK);
}
} else {
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;
switch (self->treeConfig) {
case TREE_212:
INT sMin, sNorm, sReal, sImag;
sReal = fMin(getScalefactor(&qmfOutputRealDry[i_LF][BP_GF_START],
cplxBands - BP_GF_START),
getScalefactor(&qmfOutputRealDry[i_RF][BP_GF_START],
cplxBands - BP_GF_START));
sImag = fMin(getScalefactor(&qmfOutputImagDry[i_LF][BP_GF_START],
cplxBands - BP_GF_START),
getScalefactor(&qmfOutputImagDry[i_RF][BP_GF_START],
cplxBands - BP_GF_START));
sMin = fMin(sReal, sImag) - 1;
for (n = BP_GF_START; n < cplxBands; n++) {
dmxReal0 = qmfOutputRealDry[i_LF][n] + qmfOutputRealDry[i_RF][n];
dmxImag0 = qmfOutputImagDry[i_LF][n] + qmfOutputImagDry[i_RF][n];
DRY_ENER_SUM_CPLX(DryEner0, dmxReal0, dmxImag0, n);
dmxReal0 = scaleValue(qmfOutputRealDry[i_LF][n], sMin) +
scaleValue(qmfOutputRealDry[i_RF][n], sMin);
dmxImag0 = scaleValue(qmfOutputImagDry[i_LF][n], sMin) +
scaleValue(qmfOutputImagDry[i_RF][n], sMin);
DryEner0 += (fMultDiv2(fPow2Div2(dmxReal0), pBP[n]) +
fMultDiv2(fPow2Div2(dmxImag0), pBP[n])) >>
SF_DRY_NRG;
}
DRY_ENER_WEIGHT(DryEner0);
sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_DRY_NRG + dry_scale_dmx -
(2 * sMin) + nrgScale;
DryEner0 = scaleValueSaturate(
DryEner0, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
break;
default:;
}
@ -424,7 +431,7 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
/* normalise the 'direct' signals */
for (ch = 0; ch < self->numInputChannels; ch++) {
DryEner[ch] = DryEner[ch] << (nrgScale);
if (self->treeConfig != TREE_212) DryEner[ch] = DryEner[ch] << nrgScale;
hStpDec->runDryEner[ch] =
fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
@ -436,10 +443,8 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
}
}
if (self->treeConfig == TREE_212) {
for (; ch < MAX_INPUT_CHANNELS; ch++) {
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
}
for (; ch < MAX_INPUT_CHANNELS; ch++) {
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
}
/* normalise the 'diffuse' signals */
@ -450,14 +455,30 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
}
WetEnerX = FL2FXCONST_DBL(0.0f);
for (n = BP_GF_START; n < cplxBands; n++) {
tmp = fPow2Div2(qmfOutputRealWet[ch][n] << SF_WET);
tmp += fPow2Div2(qmfOutputImagWet[ch][n] << SF_WET);
WetEnerX += fMultDiv2(tmp, pBP[n]);
}
WET_ENER_WEIGHT(WetEnerX);
WetEnerX = WetEnerX << (nrgScale);
if (self->treeConfig == TREE_212) {
INT sMin, sNorm;
sMin = fMin(getScalefactor(&qmfOutputRealWet[ch][BP_GF_START],
cplxBands - BP_GF_START),
getScalefactor(&qmfOutputImagWet[ch][BP_GF_START],
cplxBands - BP_GF_START));
for (n = BP_GF_START; n < cplxBands; n++) {
WetEnerX +=
(fMultDiv2(fPow2Div2(scaleValue(qmfOutputRealWet[ch][n], sMin)),
pBP[n]) +
fMultDiv2(fPow2Div2(scaleValue(qmfOutputImagWet[ch][n], sMin)),
pBP[n])) >>
SF_WET_NRG;
}
sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_WET_NRG + wet_scale_dmx -
(2 * sMin) + nrgScale;
WetEnerX = scaleValueSaturate(
WetEnerX, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
} else
FDK_ASSERT(self->treeConfig == TREE_212);
hStpDec->runWetEner[ch] =
fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) +
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX);

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -123,12 +123,15 @@ static const UCHAR nBitsTsdCW_64slots[64] = {
RAM_ALIGN
LNK_SECTION_CONSTDATA
static const FIXP_STP phiTsd[8] = {
STCP(0x7fffffff, 0x00000000), STCP(0x5a82799a, 0x5a82799a),
STCP(0x00000000, 0x7fffffff), STCP(0xa57d8666, 0x5a82799a),
STCP(0x80000000, 0x00000000), STCP(0xa57d8666, 0xa57d8666),
STCP(0x00000000, 0x80000000), STCP(0x5a82799a, 0xa57d8666),
};
static const FIXP_DPK phiTsd[8] = {
{{(FIXP_DBL)0x7fffffff, (FIXP_DBL)0x00000000}},
{{(FIXP_DBL)0x5a82799a, (FIXP_DBL)0x5a82799a}},
{{(FIXP_DBL)0x00000000, (FIXP_DBL)0x7fffffff}},
{{(FIXP_DBL)0xa57d8666, (FIXP_DBL)0x5a82799a}},
{{(FIXP_DBL)0x80000000, (FIXP_DBL)0x00000000}},
{{(FIXP_DBL)0xa57d8666, (FIXP_DBL)0xa57d8666}},
{{(FIXP_DBL)0x00000000, (FIXP_DBL)0x80000000}},
{{(FIXP_DBL)0x5a82799a, (FIXP_DBL)0xa57d8666}}};
/*** Static Functions ***/
static void longmult1(USHORT a[], USHORT b, USHORT d[], int len) {
@ -333,16 +336,19 @@ void TsdApply(const int numHybridBands, const TSD_DATA *pTsdData, int *pTsdTs,
if (isTrSlot(pTsdData, ts)) {
int k;
const FIXP_STP *phi = &phiTsd[pTsdData->bsTsdTrPhaseData[ts]];
const FIXP_DPK *phi = &phiTsd[pTsdData->bsTsdTrPhaseData[ts]];
FDK_ASSERT((pTsdData->bsTsdTrPhaseData[ts] >= 0) &&
(pTsdData->bsTsdTrPhaseData[ts] < 8));
/* d = d_nonTr + v_direct * exp(j * bsTsdTrPhaseData[ts]/4 * pi ) */
for (k = TSD_START_BAND; k < numHybridBands; k++) {
FIXP_DBL tempReal, tempImag;
cplxMult(&tempReal, &tempImag, pVdirectReal[k], pVdirectImag[k], *phi);
pDnonTrReal[k] += tempReal;
pDnonTrImag[k] += tempImag;
cplxMultDiv2(&tempReal, &tempImag, pVdirectReal[k], pVdirectImag[k],
*phi);
pDnonTrReal[k] = SATURATE_LEFT_SHIFT(
(pDnonTrReal[k] >> 2) + (tempReal >> 1), 2, DFRACT_BITS);
pDnonTrImag[k] = SATURATE_LEFT_SHIFT(
(pDnonTrImag[k] >> 2) + (tempImag >> 1), 2, DFRACT_BITS);
}
}

View File

@ -130,7 +130,7 @@ Description of file contents
#define SACENC_LIB_VL1 0
#define SACENC_LIB_VL2 0
#define SACENC_LIB_TITLE "MPEG Surround Encoder"
#ifdef __ANDROID__
#ifdef SUPPRESS_BUILD_DATE_INFO
#define SACENC_LIB_BUILD_DATE ""
#define SACENC_LIB_BUILD_TIME ""
#else

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -361,15 +361,20 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
* error (0: core decoder found errors, 1: no errors).
* \param psDecoded Pointer to a buffer holding a flag. Input: PS is
* possible, Output: PS has been rendered.
* \param inDataHeadroom Headroom of the SBR input time signal to prevent
* clipping.
* \param outDataHeadroom Pointer to headroom of the SBR output time signal to
* prevent clipping.
*
* \return Error code.
*/
SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
INT_PCM *timeData, const int timeDataSize,
int *numChannels, int *sampleRate,
SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, LONG *input, LONG *timeData,
const int timeDataSize, int *numChannels,
int *sampleRate,
const FDK_channelMapDescr *const mapDescr,
const int mapIdx, const int coreDecodedOk,
UCHAR *psDecoded);
UCHAR *psDecoded, const INT inDataHeadroom,
INT *outDataHeadroom);
/**
* \brief Close SBR decoder instance and free memory.

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -897,30 +897,31 @@ void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal,
for (i = startSample; i < stopSample; i++) {
maxVal |=
(FIXP_DBL)((LONG)(sourceBufferReal[i][loBand]) ^
((LONG)sourceBufferReal[i][loBand] >> (SAMPLE_BITS - 1)));
((LONG)sourceBufferReal[i][loBand] >> (DFRACT_BITS - 1)));
maxVal |=
(FIXP_DBL)((LONG)(sourceBufferImag[i][loBand]) ^
((LONG)sourceBufferImag[i][loBand] >> (SAMPLE_BITS - 1)));
((LONG)sourceBufferImag[i][loBand] >> (DFRACT_BITS - 1)));
}
if (maxVal != FL2FX_DBL(0.0f)) {
reserve = fixMax(0, CntLeadingZeros(maxVal) - 2);
reserve = CntLeadingZeros(maxVal) - 2;
}
nrg_ov = nrg = (FIXP_DBL)0;
if (scale_nrg_ov > -31) {
for (i = startSample; i < overlap; i++) {
nrg_ov += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) +
fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >>
sum_scale_ov;
nrg_ov +=
(fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) +
fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >>
sum_scale_ov;
}
} else {
scale_nrg_ov = 0;
}
if (scale_nrg > -31) {
for (i = overlap; i < stopSample; i++) {
nrg += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) +
fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >>
nrg += (fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) +
fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >>
sum_scale;
}
} else {

View File

@ -151,6 +151,9 @@ amm-info@iis.fraunhofer.de
#include "genericStds.h" /* need FDKpow() for debug outputs */
#define MAX_SFB_NRG_HEADROOM (1)
#define MAX_VAL_NRG_HEADROOM ((((FIXP_DBL)MAXVAL_DBL) >> MAX_SFB_NRG_HEADROOM))
typedef struct {
FIXP_DBL nrgRef[MAX_FREQ_COEFFS];
FIXP_DBL nrgEst[MAX_FREQ_COEFFS];
@ -699,20 +702,11 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
gain_sf[i] += gamma_sf + 1; /* +1 because of fMultDiv2() */
/* set gain to at least 0.2f */
FIXP_DBL point_two = FL2FXCONST_DBL(0.8f); /* scaled up by 2 */
int point_two_sf = -2;
FIXP_DBL tmp = gain[i];
if (point_two_sf < gain_sf[i]) {
point_two >>= gain_sf[i] - point_two_sf;
} else {
tmp >>= point_two_sf - gain_sf[i];
}
/* limit and calculate gain[i]^2 too */
FIXP_DBL gain_pow2;
int gain_pow2_sf;
if (tmp < point_two) {
if (fIsLessThan(gain[i], gain_sf[i], FL2FXCONST_DBL(0.2f), 0)) {
gain[i] = FL2FXCONST_DBL(0.8f);
gain_sf[i] = -2;
gain_pow2 = FL2FXCONST_DBL(0.64f);
@ -739,7 +733,8 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf);
total_power_high_after_sf = new_summand_sf;
} else if (new_summand_sf < total_power_high_after_sf) {
subsample_power_high[i] >>= total_power_high_after_sf - new_summand_sf;
subsample_power_high[i] >>=
fMin(DFRACT_BITS - 1, total_power_high_after_sf - new_summand_sf);
}
total_power_high_after += subsample_power_high[i] >> preShift2;
}
@ -985,7 +980,8 @@ void calculateSbrEnvelope(
*/
if (!useLP)
adj_e = h_sbr_cal_env->filtBufferNoise_e -
getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands);
getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands) +
(INT)MAX_SFB_NRG_HEADROOM;
/*
Scan for maximum reference energy to be able
@ -1005,7 +1001,7 @@ void calculateSbrEnvelope(
- Smoothing can smear high gains of the previous envelope into the
current
*/
maxSfbNrg_e += 6;
maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
adj_e = maxSfbNrg_e;
// final_e should not exist for PVC fixfix framing
@ -1031,7 +1027,7 @@ void calculateSbrEnvelope(
- Smoothing can smear high gains of the previous envelope into the
current
*/
maxSfbNrg_e += 6;
maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
if (borders[i] < hHeaderData->numberTimeSlots)
/* This envelope affects timeslots that belong to the output frame */
@ -1477,17 +1473,15 @@ void calculateSbrEnvelope(
for (k = 0; k < noSubbands; k++) {
int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1);
pNrgs->nrgGain[k] >>= fixMin(sc, DFRACT_BITS - 1);
pNrgs->nrgGain_e[k] += sc;
if (sc > 31)
sc = 31;
pNrgs->nrgGain[k] >>= sc;
}
if (!useLP) {
for (k = 0; k < noSubbands; k++) {
int sc =
scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1);
h_sbr_cal_env->filtBuffer[k] >>= sc;
h_sbr_cal_env->filtBuffer[k] >>= fixMin(sc, DFRACT_BITS - 1);
}
}
@ -1578,12 +1572,13 @@ void calculateSbrEnvelope(
FDK_ASSERT(!iTES_enable); /* not supported */
if (flags & SBRDEC_ELD_GRID) {
/* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */
adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband], pNrgs,
&h_sbr_cal_env->harmIndex, lowSubband,
noSubbands,
fMin(scale_change, DFRACT_BITS - 1),
noNoiseFlag, &h_sbr_cal_env->phaseIndex,
EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale);
adjustTimeSlot_EldGrid(
&analysBufferReal[j][lowSubband], pNrgs,
&h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
&h_sbr_cal_env->phaseIndex,
fMax(EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale,
-(DFRACT_BITS - 1)));
} else {
adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs,
&h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
@ -1832,7 +1827,8 @@ static void equalizeFiltBufferExp(
diff = (int)(nrgGain_e[band] - filtBuffer_e[band]);
if (diff > 0) {
filtBuffer[band] >>=
diff; /* Compensate for the scale change by shifting the mantissa. */
fMin(diff, DFRACT_BITS - 1); /* Compensate for the scale change by
shifting the mantissa. */
filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */
} else if (diff < 0) {
/* The buffered gains seem to be larger, but maybe there
@ -1852,8 +1848,8 @@ static void equalizeFiltBufferExp(
filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */
/* For the remaining difference, change the new gain value */
diff = fixMin(-(reserve + diff), DFRACT_BITS - 1);
nrgGain[band] >>= diff;
diff = -(reserve + diff);
nrgGain[band] >>= fMin(diff, DFRACT_BITS - 1);
nrgGain_e[band] += diff;
}
}
@ -2425,6 +2421,9 @@ static void adjustTimeSlot_EldGrid(
const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0];
const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0];
const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
const FIXP_DBL min_val = -max_val;
*(ptrReal - 1) = fAddSaturate(
*(ptrReal - 1),
SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]),
@ -2437,7 +2436,8 @@ static void adjustTimeSlot_EldGrid(
FIXP_DBL sineLevel_curr = *pSineLevel++;
phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
<< scale_change;
sbNoise = *pNoiseLevel++;
if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
signalReal +=
@ -2471,7 +2471,8 @@ static void adjustTimeSlot_EldGrid(
FIXP_DBL sineLevel_curr = *pSineLevel++;
phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
<< scale_change;
sbNoise = *pNoiseLevel++;
if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
signalReal +=
@ -2511,6 +2512,8 @@ static void adjustTimeSlotLC(
FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
int tone_count = 0;
int sineSign = 1;
const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
const FIXP_DBL min_val = -max_val;
#define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f))
#define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.16773f))
@ -2526,7 +2529,8 @@ static void adjustTimeSlotLC(
of the signal and should be carried out with full accuracy
(supplying #FRACT_BITS valid bits).
*/
signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
<< scale_change;
sineLevel = *pSineLevel++;
sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
@ -2554,10 +2558,10 @@ static void adjustTimeSlotLC(
/* save switch and compare operations and reduce to XOR statement */
if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) {
*(ptrReal - 1) += tmp1;
*(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), tmp1);
signalReal -= tmp2;
} else {
*(ptrReal - 1) -= tmp1;
*(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), -tmp1);
signalReal += tmp2;
}
*ptrReal++ = signalReal;
@ -2588,7 +2592,9 @@ static void adjustTimeSlotLC(
/* The next multiplication constitutes the actual envelope adjustment of
* the signal. */
signalReal += fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
signalReal +=
fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
<< scale_change;
pNoiseLevel++;
*ptrReal++ = signalReal;
@ -2601,7 +2607,8 @@ static void adjustTimeSlotLC(
index++;
/* The next multiplication constitutes the actual envelope adjustment of
* the signal. */
signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
<< scale_change;
if (*pSineLevel++ != FL2FXCONST_DBL(0.0f))
tone_count++;
@ -2629,7 +2636,8 @@ static void adjustTimeSlotLC(
index++;
/* The next multiplication constitutes the actual envelope adjustment of the
* signal. */
signalReal = fMultDiv2(*ptrReal, *pGain) << ((int)scale_change);
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain), max_val), min_val)
<< scale_change;
sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f));
sineLevel = pSineLevel[0];
@ -2698,6 +2706,9 @@ static void adjustTimeSlotHQ_GainAndNoise(
/*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
int index = *ptrPhaseIndex;
int shift;
FIXP_DBL max_val_noise = 0, min_val_noise = 0;
const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
const FIXP_DBL min_val = -max_val;
*ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
@ -2707,6 +2718,8 @@ static void adjustTimeSlotHQ_GainAndNoise(
shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
} else {
shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
min_val_noise = -max_val_noise;
}
if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
@ -2722,8 +2735,10 @@ static void adjustTimeSlotHQ_GainAndNoise(
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
fMult(direct_ratio, noiseLevel[k]);
} else {
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) +
fMult(direct_ratio, noiseLevel[k]);
smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
smoothedNoise =
(fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
fMult(direct_ratio, noiseLevel[k]);
}
/*
@ -2731,8 +2746,12 @@ static void adjustTimeSlotHQ_GainAndNoise(
of the signal and should be carried out with full accuracy
(supplying #DFRACT_BITS valid bits).
*/
signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change);
signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change);
signalReal =
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
<< scale_change;
signalImag =
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
<< scale_change;
index++;
@ -2754,8 +2773,12 @@ static void adjustTimeSlotHQ_GainAndNoise(
} else {
for (k = 0; k < noSubbands; k++) {
smoothedGain = gain[k];
signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
signalReal =
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
<< scale_change;
signalImag =
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
<< scale_change;
index++;
@ -2861,6 +2884,9 @@ static void adjustTimeSlotHQ(
int freqInvFlag = (lowSubband & 1);
FIXP_DBL sineLevel;
int shift;
FIXP_DBL max_val_noise = 0, min_val_noise = 0;
const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
const FIXP_DBL min_val = -max_val;
*ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
*ptrHarmIndex = (harmIndex + 1) & 3;
@ -2876,10 +2902,13 @@ static void adjustTimeSlotHQ(
filtBufferNoiseShift +=
1; /* due to later use of fMultDiv2 instead of fMult */
if (filtBufferNoiseShift < 0)
if (filtBufferNoiseShift < 0) {
shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
else
} else {
shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
min_val_noise = -max_val_noise;
}
if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
for (k = 0; k < noSubbands; k++) {
@ -2895,8 +2924,10 @@ static void adjustTimeSlotHQ(
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
fMult(direct_ratio, noiseLevel[k]);
} else {
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) +
fMult(direct_ratio, noiseLevel[k]);
smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
smoothedNoise =
(fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
fMult(direct_ratio, noiseLevel[k]);
}
/*
@ -2904,8 +2935,12 @@ static void adjustTimeSlotHQ(
of the signal and should be carried out with full accuracy
(supplying #DFRACT_BITS valid bits).
*/
signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change);
signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change);
signalReal =
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
<< scale_change;
signalImag =
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
<< scale_change;
index++;
@ -2958,8 +2993,12 @@ static void adjustTimeSlotHQ(
} else {
for (k = 0; k < noSubbands; k++) {
smoothedGain = gain[k];
signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
signalReal =
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
<< scale_change;
signalImag =
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
<< scale_change;
index++;
@ -3143,6 +3182,11 @@ ResetLimiterBands(
return SBRDEC_UNSUPPORTED_CONFIG;
}
/* Restrict maximum value of limiter band table */
if (workLimiterBandTable[tempNoLim] > highSubband) {
return SBRDEC_UNSUPPORTED_CONFIG;
}
/* Copy limiterbands from working buffer into final destination */
for (k = 0; k <= nBands; k++) {
limiterBandTable[k] = workLimiterBandTable[k];

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -957,7 +957,7 @@ QmfTransposerCreate(HANDLE_HBE_TRANSPOSER* hQmfTransposer, const int frameSize,
hQmfTran->qmfOutBufSize = 2 * (hQmfTran->noCols / 2 + QMF_WIN_LEN - 1);
hQmfTran->inBuf_F =
(INT_PCM*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(INT_PCM));
(LONG*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(LONG));
/* buffered time signal needs to be delayed by synthesis_size; max
* synthesis_size = 20; */
if (hQmfTran->inBuf_F == NULL) {
@ -1339,7 +1339,7 @@ static void addHighBandPart(FIXP_DBL g_r_m, FIXP_DBL g_i_m, INT g_e,
g_r_m = fMultDiv2(tmp_r, factor_m) << shift;
g_i_m = fMultDiv2(tmp_i, factor_m) << shift;
g_e = scale_factor_hbe - (g_e + factor_e + gammaCenter_e + add);
fMax((INT)0, g_e);
g_e = fMax((INT)0, g_e);
*qmfHBEBufReal_F += g_r_m >> g_e;
*qmfHBEBufImag_F += g_i_m >> g_e;
}

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -132,6 +132,9 @@ typedef enum {
} KEEP_STATES_SYNCED_MODE;
struct hbeTransposer {
FIXP_DBL anaQmfStates[HBE_QMF_FILTER_STATE_ANA_SIZE];
FIXP_QSS synQmfStates[HBE_QMF_FILTER_STATE_SYN_SIZE];
int xOverQmf[MAX_NUM_PATCHES_HBE];
int maxStretch;
@ -144,7 +147,7 @@ struct hbeTransposer {
int stopBand;
int bSbr41;
INT_PCM *inBuf_F;
LONG *inBuf_F;
FIXP_DBL **qmfInBufReal_F;
FIXP_DBL **qmfInBufImag_F;
@ -156,9 +159,6 @@ struct hbeTransposer {
FIXP_DBL const *synthesisQmfPreModCos_F;
FIXP_DBL const *synthesisQmfPreModSin_F;
FIXP_QAS anaQmfStates[HBE_QMF_FILTER_STATE_ANA_SIZE];
FIXP_QSS synQmfStates[HBE_QMF_FILTER_STATE_SYN_SIZE];
FIXP_DBL **qmfHBEBufReal_F;
FIXP_DBL **qmfHBEBufImag_F;

View File

@ -1014,8 +1014,8 @@ void lppTransposerHBE(
pSettings->nCols) +
lowBandShift);
dynamicScale = fixMax(
0, dynamicScale - 1); /* one additional bit headroom to prevent -1.0 */
dynamicScale =
dynamicScale - 1; /* one additional bit headroom to prevent -1.0 */
/*
Scale temporal QMF buffer.
@ -1194,6 +1194,9 @@ void lppTransposerHBE(
} else { /* bw <= 0 */
int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
dynamicScale +=
1; /* prevent negativ scale factor due to 'one additional bit
headroom' */
for (i = startSample; i < stopSample; i++) {
FIXP_DBL accu1, accu2;
@ -1210,9 +1213,9 @@ void lppTransposerHBE(
dynamicScale;
qmfBufferReal[i][loBand] =
(lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << 1);
(lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << (1 + 1));
qmfBufferImag[i][loBand] =
(lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << 1);
(lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << (1 + 1));
}
} /* bw <= 0 */

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -534,7 +534,8 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
for (band = sg_borders[ksg]; band < sg_borders[ksg + 1]; band++) {
/* The division by 8 == (RATE*lbw) is required algorithmically */
E[ksg] += (fPow2Div2(qmfR[band]) + fPow2Div2(qmfI[band])) >> 2;
E[ksg] +=
((fPow2Div2(qmfR[band]) >> 1) + (fPow2Div2(qmfI[band]) >> 1)) >> 3;
}
}
}
@ -542,7 +543,7 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
if (E[ksg] > (FIXP_DBL)0) {
/* 10/log2(10) = 0.752574989159953 * 2^2 */
int exp_log;
FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent, &exp_log);
FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent + 2, &exp_log);
nrg = fMult(nrg, FL2FXCONST_SGL(LOG10FAC));
nrg = scaleValue(nrg, exp_log - PVC_ESG_EXP + 2);
pEsg[ksg] = fMax(nrg, FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)));
@ -603,22 +604,22 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
E_high_exp[ksg] = 0;
/* residual part */
accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP +
accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP - 2 +
pPvcDynamicData->pScalingCoef[3]);
/* linear combination of lower grouped energies part */
for (kb = 0; kb < PVC_NBLOW; kb++) {
predCoeff = (FIXP_SGL)(
(SHORT)(SCHAR)pTab1[kb * pPvcDynamicData->nbHigh + ksg] << 8);
predCoeff_exp = pPvcDynamicData->pScalingCoef[kb] +
1; /* +1 to compensate for Div2 */
accu += fMultDiv2(E[kb], predCoeff) << predCoeff_exp;
predCoeff_exp = -(pPvcDynamicData->pScalingCoef[kb] + 1 -
2); /* +1 to compensate for Div2; -2 for accu */
accu += fMultDiv2(E[kb], predCoeff) >> predCoeff_exp;
}
/* convert back to linear domain */
accu = fMult(accu, FL2FXCONST_SGL(LOG10FAC_INV));
accu = f2Pow(
accu, PVC_ESG_EXP - 1,
&predCoeff_exp); /* -1 compensates for exponent of LOG10FAC_INV */
accu = f2Pow(accu, PVC_ESG_EXP - 1 + 2,
&predCoeff_exp); /* -1 compensates for exponent of
LOG10FAC_INV; +2 for accu */
predictedEsgSlot[ksg] = accu;
E_high_exp[ksg] = predCoeff_exp;
if (predCoeff_exp > E_high_exp_max) {
@ -628,8 +629,8 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
/* rescale output vector according to largest exponent */
for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
int scale = E_high_exp[ksg] - E_high_exp_max;
predictedEsgSlot[ksg] = scaleValue(predictedEsgSlot[ksg], scale);
int scale = fMin(E_high_exp_max - E_high_exp[ksg], DFRACT_BITS - 1);
predictedEsgSlot[ksg] = predictedEsgSlot[ksg] >> scale;
}
*predictedEsg_exp = E_high_exp_max;
}

View File

@ -1,194 +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);
}
if (CrcNrBitsRest > 0) {
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);
}

View File

@ -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

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@ -259,17 +259,18 @@ static void copyHarmonicSpectrum(int *xOverQmf, FIXP_DBL **qmfReal,
void sbr_dec(
HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
INT_PCM *timeIn, /*!< pointer to input time signal */
INT_PCM *timeOut, /*!< pointer to output time signal */
LONG *timeIn, /*!< pointer to input time signal */
LONG *timeOut, /*!< pointer to output time signal */
HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */
INT_PCM *timeOutRight, /*!< pointer to output time signal */
LONG *timeOutRight, /*!< pointer to output time signal */
const int strideOut, /*!< Time data traversal strideOut */
HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
HANDLE_SBR_PREV_FRAME_DATA
hPrevFrameData, /*!< Some control data of last frame */
const int applyProcessing, /*!< Flag for SBR operation */
HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize) {
HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize,
const INT sbrInDataHeadroom) {
int i, slot, reserve;
int saveLbScale;
int lastSlotOffs;
@ -278,7 +279,7 @@ void sbr_dec(
/* temporary pointer / variable for QMF;
required as we want to use temporary buffer
creating one frame delay for HBE in LP mode */
INT_PCM *pTimeInQmf = timeIn;
LONG *pTimeInQmf = timeIn;
/* Number of QMF timeslots in the overlap buffer: */
int ov_len = hSbrDec->LppTrans.pSettings->overlap;
@ -341,8 +342,8 @@ void sbr_dec(
} else {
C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * (64));
qmfAnalysisFiltering(&hSbrDec->qmfDomainInCh->fb, pReal, pImag,
&hSbrDec->qmfDomainInCh->scaling, pTimeInQmf, 0, 1,
qmfTemp);
&hSbrDec->qmfDomainInCh->scaling, pTimeInQmf,
0 + sbrInDataHeadroom, 1, qmfTemp);
C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * (64));
}
@ -658,7 +659,7 @@ void sbr_dec(
if (!(flags & SBRDEC_PS_DECODED)) {
if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
int outScalefactor = 0;
int outScalefactor = -(8);
if (h_ps_d != NULL) {
h_ps_d->procFrameBased = 1; /* we here do frame based processing */
@ -743,6 +744,7 @@ void sbr_dec(
*/
FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <=
QMF_MAX_SYNTHESIS_BANDS);
qmfChangeOutScalefactor(synQmfRight, -(8));
FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates,
9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis *
sizeof(FIXP_QSS));
@ -814,7 +816,8 @@ void sbr_dec(
: scaleFactorLowBand_no_ov,
scaleFactorHighBand, synQmf->lsb, synQmf->usb);
outScalefactorL = outScalefactorR = 1; /* psDiffScale! (MPEG-PS) */
outScalefactorL = outScalefactorR =
1 + sbrInDataHeadroom; /* psDiffScale! (MPEG-PS) */
}
sbrDecoder_drcApplySlot(/* right channel */
@ -831,6 +834,9 @@ void sbr_dec(
outScalefactorL += maxShift;
if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
qmfChangeOutScalefactor(synQmf, -(8));
qmfChangeOutScalefactor(synQmfRight, -(8));
qmfSynthesisFilteringSlot(
synQmfRight, rQmfReal, /* QMF real buffer */
rQmfImag, /* QMF imag buffer */

Some files were not shown because too many files have changed in this diff Show More