|
From 022f1b86ef2f992c1c5623719e403b9b28e1becc Mon Sep 17 00:00:00 2001
|
|
From: Wim Taymans <wtaymans@redhat.com>
|
|
Date: Mon, 24 Jun 2019 16:26:20 +0200
|
|
Subject: Remove HCR, RVLC, error concealment
|
|
|
|
---
|
|
Makefile.am | 7 -
|
|
Makefile.vc | 7 -
|
|
libAACdec/src/aac_ram.h | 3 -
|
|
libAACdec/src/aac_rom.cpp | 96 --
|
|
libAACdec/src/aac_rom.h | 4 +-
|
|
libAACdec/src/aacdec_hcr.cpp | 1498 ---------------------------
|
|
libAACdec/src/aacdec_hcr.h | 128 ---
|
|
libAACdec/src/aacdec_hcr_bit.cpp | 164 ---
|
|
libAACdec/src/aacdec_hcr_bit.h | 114 ---
|
|
libAACdec/src/aacdec_hcr_types.h | 432 --------
|
|
libAACdec/src/aacdec_hcrs.cpp | 1551 ----------------------------
|
|
libAACdec/src/aacdec_hcrs.h | 176 ----
|
|
libAACdec/src/aacdecoder.cpp | 91 +-
|
|
libAACdec/src/aacdecoder.h | 3 -
|
|
libAACdec/src/aacdecoder_lib.cpp | 73 +-
|
|
libAACdec/src/block.cpp | 59 +-
|
|
libAACdec/src/channel.cpp | 19 +-
|
|
libAACdec/src/channelinfo.h | 22 -
|
|
libAACdec/src/conceal.cpp | 2095 --------------------------------------
|
|
libAACdec/src/conceal.h | 152 ---
|
|
libAACdec/src/conceal_types.h | 203 ----
|
|
libAACdec/src/rvlc.cpp | 1217 ----------------------
|
|
libAACdec/src/rvlc.h | 153 ---
|
|
libAACdec/src/rvlc_info.h | 204 ----
|
|
libAACdec/src/rvlcbit.cpp | 148 ---
|
|
libAACdec/src/rvlcbit.h | 111 --
|
|
libAACdec/src/rvlcconceal.cpp | 787 --------------
|
|
libAACdec/src/rvlcconceal.h | 127 ---
|
|
libAACdec/src/usacdec_lpd.cpp | 20 +-
|
|
29 files changed, 21 insertions(+), 9643 deletions(-)
|
|
delete mode 100644 libAACdec/src/aacdec_hcr.cpp
|
|
delete mode 100644 libAACdec/src/aacdec_hcr.h
|
|
delete mode 100644 libAACdec/src/aacdec_hcr_bit.cpp
|
|
delete mode 100644 libAACdec/src/aacdec_hcr_bit.h
|
|
delete mode 100644 libAACdec/src/aacdec_hcr_types.h
|
|
delete mode 100644 libAACdec/src/aacdec_hcrs.cpp
|
|
delete mode 100644 libAACdec/src/aacdec_hcrs.h
|
|
delete mode 100644 libAACdec/src/conceal.cpp
|
|
delete mode 100644 libAACdec/src/conceal.h
|
|
delete mode 100644 libAACdec/src/conceal_types.h
|
|
delete mode 100644 libAACdec/src/rvlc.cpp
|
|
delete mode 100644 libAACdec/src/rvlc.h
|
|
delete mode 100644 libAACdec/src/rvlc_info.h
|
|
delete mode 100644 libAACdec/src/rvlcbit.cpp
|
|
delete mode 100644 libAACdec/src/rvlcbit.h
|
|
delete mode 100644 libAACdec/src/rvlcconceal.cpp
|
|
delete mode 100644 libAACdec/src/rvlcconceal.h
|
|
|
|
--- a/Makefile.am
|
|
+++ b/Makefile.am
|
|
@@ -50,9 +50,6 @@ AACDEC_SRC = \
|
|
libAACdec/src/aac_ram.cpp \
|
|
libAACdec/src/aac_rom.cpp \
|
|
libAACdec/src/aacdec_drc.cpp \
|
|
- libAACdec/src/aacdec_hcr.cpp \
|
|
- libAACdec/src/aacdec_hcr_bit.cpp \
|
|
- libAACdec/src/aacdec_hcrs.cpp \
|
|
libAACdec/src/aacdec_pns.cpp \
|
|
libAACdec/src/aacdec_tns.cpp \
|
|
libAACdec/src/aacdecoder.cpp \
|
|
@@ -60,12 +57,8 @@ AACDEC_SRC = \
|
|
libAACdec/src/block.cpp \
|
|
libAACdec/src/channel.cpp \
|
|
libAACdec/src/channelinfo.cpp \
|
|
- libAACdec/src/conceal.cpp \
|
|
libAACdec/src/ldfiltbank.cpp \
|
|
libAACdec/src/pulsedata.cpp \
|
|
- libAACdec/src/rvlc.cpp \
|
|
- libAACdec/src/rvlcbit.cpp \
|
|
- libAACdec/src/rvlcconceal.cpp \
|
|
libAACdec/src/stereo.cpp \
|
|
libAACdec/src/usacdec_ace_d4t64.cpp \
|
|
libAACdec/src/usacdec_ace_ltp.cpp \
|
|
--- a/Makefile.vc
|
|
+++ b/Makefile.vc
|
|
@@ -34,9 +34,6 @@ AACDEC_SRC = \
|
|
libAACdec/src/aac_ram.cpp \
|
|
libAACdec/src/aac_rom.cpp \
|
|
libAACdec/src/aacdec_drc.cpp \
|
|
- libAACdec/src/aacdec_hcr.cpp \
|
|
- libAACdec/src/aacdec_hcr_bit.cpp \
|
|
- libAACdec/src/aacdec_hcrs.cpp \
|
|
libAACdec/src/aacdec_pns.cpp \
|
|
libAACdec/src/aacdec_tns.cpp \
|
|
libAACdec/src/aacdecoder.cpp \
|
|
@@ -44,12 +41,8 @@ AACDEC_SRC = \
|
|
libAACdec/src/block.cpp \
|
|
libAACdec/src/channel.cpp \
|
|
libAACdec/src/channelinfo.cpp \
|
|
- libAACdec/src/conceal.cpp \
|
|
libAACdec/src/ldfiltbank.cpp \
|
|
libAACdec/src/pulsedata.cpp \
|
|
- libAACdec/src/rvlc.cpp \
|
|
- libAACdec/src/rvlcbit.cpp \
|
|
- libAACdec/src/rvlcconceal.cpp \
|
|
libAACdec/src/stereo.cpp \
|
|
libAACdec/src/usacdec_ace_d4t64.cpp \
|
|
libAACdec/src/usacdec_ace_ltp.cpp \
|
|
--- a/libAACdec/src/aac_ram.h
|
|
+++ b/libAACdec/src/aac_ram.h
|
|
@@ -111,9 +111,6 @@ amm-info@iis.fraunhofer.de
|
|
|
|
#include "ac_arith_coder.h"
|
|
|
|
-#include "aacdec_hcr_types.h"
|
|
-#include "aacdec_hcr.h"
|
|
-
|
|
/* End of formal fix.h */
|
|
|
|
#define MAX_SYNCHS 10
|
|
--- a/libAACdec/src/aac_rom.cpp
|
|
+++ b/libAACdec/src/aac_rom.cpp
|
|
@@ -1583,102 +1583,6 @@ const SCHAR *aQuantTable[] = {
|
|
aValTab24, /* 30 6 */
|
|
aValTab24}; /* 31 6 */
|
|
|
|
-/* arrays for HCR_TABLE_INFO structures */
|
|
-/* maximum length of codeword in each codebook */
|
|
-/* codebook: 0,1, 2,3, 4, 5, 6, 7, 8, 9,
|
|
- * 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 */
|
|
-const UCHAR aMaxCwLen[MAX_CB] = {0, 11, 9, 20, 16, 13, 11, 14, 12, 17, 14,
|
|
- 49, 0, 0, 0, 0, 14, 17, 21, 21, 25, 25,
|
|
- 29, 29, 29, 29, 33, 33, 33, 37, 37, 41};
|
|
-
|
|
-/* 11 13 15 17 19
|
|
- * 21 23 25 27 39 31 */
|
|
-/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20
|
|
- * 22 24 26 28 30 */
|
|
-const UCHAR aDimCb[MAX_CB] = {
|
|
- 2, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
|
|
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; /* codebook dimension -
|
|
- zero cb got a
|
|
- dimension of 2 */
|
|
-
|
|
-/* 11 13 15 17 19
|
|
- * 21 23 25 27 39 31 */
|
|
-/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20
|
|
- * 22 24 26 28 30 */
|
|
-const UCHAR aDimCbShift[MAX_CB] = {
|
|
- 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
|
|
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; /* codebook dimension */
|
|
-
|
|
-/* 1 -> decode sign bits */
|
|
-/* 0 -> decode no sign bits 11 13 15 17 19 21
|
|
- * 23 25 27 39 31 */
|
|
-/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20 22
|
|
- * 24 26 28 30 */
|
|
-const UCHAR aSignCb[MAX_CB] = {0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0,
|
|
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
|
-
|
|
-/* arrays for HCR_CB_PAIRS structures */
|
|
-const UCHAR aMinOfCbPair[MAX_CB_PAIRS] = {0, 1, 3, 5, 7, 9, 16, 17,
|
|
- 18, 19, 20, 21, 22, 23, 24, 25,
|
|
- 26, 27, 28, 29, 30, 31, 11};
|
|
-const UCHAR aMaxOfCbPair[MAX_CB_PAIRS] = {0, 2, 4, 6, 8, 10, 16, 17,
|
|
- 18, 19, 20, 21, 22, 23, 24, 25,
|
|
- 26, 27, 28, 29, 30, 31, 11};
|
|
-
|
|
-/* priorities of codebooks */
|
|
-const UCHAR aCbPriority[MAX_CB] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
|
|
- 22, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11,
|
|
- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
|
|
-
|
|
-const SCHAR aCodebook2StartInt[] = {STOP_THIS_STATE, /* cb 0 */
|
|
- BODY_ONLY, /* cb 1 */
|
|
- BODY_ONLY, /* cb 2 */
|
|
- BODY_SIGN__BODY, /* cb 3 */
|
|
- BODY_SIGN__BODY, /* cb 4 */
|
|
- BODY_ONLY, /* cb 5 */
|
|
- BODY_ONLY, /* cb 6 */
|
|
- BODY_SIGN__BODY, /* cb 7 */
|
|
- BODY_SIGN__BODY, /* cb 8 */
|
|
- BODY_SIGN__BODY, /* cb 9 */
|
|
- BODY_SIGN__BODY, /* cb 10 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 11 */
|
|
- STOP_THIS_STATE, /* cb 12 */
|
|
- STOP_THIS_STATE, /* cb 13 */
|
|
- STOP_THIS_STATE, /* cb 14 */
|
|
- STOP_THIS_STATE, /* cb 15 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 16 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 17 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 18 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 19 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 20 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 21 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 22 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 23 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 24 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 25 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 26 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 27 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 28 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 29 */
|
|
- BODY_SIGN_ESC__BODY, /* cb 30 */
|
|
- BODY_SIGN_ESC__BODY}; /* cb 31 */
|
|
-
|
|
-const STATEFUNC aStateConstant2State[] = {
|
|
- NULL, /* 0 = STOP_THIS_STATE */
|
|
- Hcr_State_BODY_ONLY, /* 1 = BODY_ONLY */
|
|
- Hcr_State_BODY_SIGN__BODY, /* 2 = BODY_SIGN__BODY */
|
|
- Hcr_State_BODY_SIGN__SIGN, /* 3 = BODY_SIGN__SIGN */
|
|
- Hcr_State_BODY_SIGN_ESC__BODY, /* 4 = BODY_SIGN_ESC__BODY */
|
|
- Hcr_State_BODY_SIGN_ESC__SIGN, /* 5 = BODY_SIGN_ESC__SIGN */
|
|
- Hcr_State_BODY_SIGN_ESC__ESC_PREFIX, /* 6 = BODY_SIGN_ESC__ESC_PREFIX */
|
|
- Hcr_State_BODY_SIGN_ESC__ESC_WORD}; /* 7 = BODY_SIGN_ESC__ESC_WORD */
|
|
-
|
|
-/* CB: 0 1 2 3 4 5 6 7 8 9 10 12
|
|
- * 14 16 18 20 22 24 26 28 30 */
|
|
-const USHORT aLargestAbsoluteValue[MAX_CB] = {
|
|
- 0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12,
|
|
- 8191, 0, 0, 0, 0, 15, 31, 47, 63, 95, 127,
|
|
- 159, 191, 223, 255, 319, 383, 511, 767, 1023, 2047}; /* lav */
|
|
/* CB: 11 13
|
|
* 15 17 19 21 23 25 27 39 31 */
|
|
|
|
--- a/libAACdec/src/aac_rom.h
|
|
+++ b/libAACdec/src/aac_rom.h
|
|
@@ -105,8 +105,6 @@ amm-info@iis.fraunhofer.de
|
|
|
|
#include "common_fix.h"
|
|
#include "FDK_audio.h"
|
|
-#include "aacdec_hcr_types.h"
|
|
-#include "aacdec_hcrs.h"
|
|
|
|
#define PCM_DEC FIXP_DBL
|
|
#define MAXVAL_PCM_DEC MAXVAL_DBL
|
|
@@ -165,7 +163,7 @@ typedef struct {
|
|
extern const CodeBookDescription AACcodeBookDescriptionTable[13];
|
|
extern const CodeBookDescription AACcodeBookDescriptionSCL;
|
|
|
|
-extern const STATEFUNC aStateConstant2State[];
|
|
+#define MAX_CB 32 /* last used CB is cb #31 when VCB11 is used */
|
|
|
|
extern const SCHAR aCodebook2StartInt[];
|
|
|
|
--- a/libAACdec/src/aacdec_hcr.cpp
|
|
+++ /dev/null
|
|
@@ -1,1498 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s): Robert Weidner (DSP Solutions)
|
|
-
|
|
- Description: HCR Decoder: HCR initialization, preprocess HCR sideinfo,
|
|
- decode priority codewords (PCWs)
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-#include "aacdec_hcr.h"
|
|
-
|
|
-#include "aacdec_hcr_types.h"
|
|
-#include "aacdec_hcr_bit.h"
|
|
-#include "aacdec_hcrs.h"
|
|
-#include "aac_ram.h"
|
|
-#include "aac_rom.h"
|
|
-#include "channel.h"
|
|
-#include "block.h"
|
|
-
|
|
-#include "aacdecoder.h" /* for ID_CPE, ID_SCE ... */
|
|
-#include "FDK_bitstream.h"
|
|
-
|
|
-extern int mlFileChCurr;
|
|
-
|
|
-static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine,
|
|
- UINT *errorWord);
|
|
-
|
|
-static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword,
|
|
- SHORT lengthOfReorderedSpectralData,
|
|
- UINT *errorWord);
|
|
-
|
|
-static void HcrCalcNumCodeword(H_HCR_INFO pHcr);
|
|
-static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr);
|
|
-static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr);
|
|
-static void HcrExtendedSectionInfo(H_HCR_INFO pHcr);
|
|
-
|
|
-static void DeriveNumberOfExtendedSortedSectionsInSets(
|
|
- UINT numSegment, USHORT *pNumExtendedSortedCodewordInSection,
|
|
- int numExtendedSortedCodewordInSectionIdx,
|
|
- USHORT *pNumExtendedSortedSectionsInSets,
|
|
- int numExtendedSortedSectionsInSetsIdx);
|
|
-
|
|
-static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|
- INT quantSpecCoef, INT *pLeftStartOfSegment,
|
|
- SCHAR *pRemainingBitsInSegment,
|
|
- int *pNumDecodedBits);
|
|
-
|
|
-static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|
- UINT codebookDim, const SCHAR *pQuantVal,
|
|
- FIXP_DBL *pQuantSpecCoef, int *quantSpecCoefIdx,
|
|
- INT *pLeftStartOfSegment,
|
|
- SCHAR *pRemainingBitsInSegment, int *pNumDecodedBits);
|
|
-
|
|
-static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|
- const UINT *pCurrentTree,
|
|
- const SCHAR *pQuantValBase,
|
|
- INT *pLeftStartOfSegment,
|
|
- SCHAR *pRemainingBitsInSegment,
|
|
- int *pNumDecodedBits);
|
|
-
|
|
-static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr);
|
|
-
|
|
-static void HcrReorderQuantizedSpectralCoefficients(
|
|
- H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- const SamplingRateInfo *pSamplingRateInfo);
|
|
-
|
|
-static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment,
|
|
- H_HCR_INFO pHcr, PCW_TYPE kind,
|
|
- FIXP_DBL *qsc_base_of_cw,
|
|
- UCHAR dimension);
|
|
-
|
|
-static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr);
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Check if codebook and numSect are within allowed range
|
|
-(short only)
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine,
|
|
- UINT *errorWord) {
|
|
- if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL) {
|
|
- *errorWord |= CB_OUT_OF_RANGE_SHORT_BLOCK;
|
|
- }
|
|
- if (numLine < 0 || numLine > 1024) {
|
|
- *errorWord |= LINE_IN_SECT_OUT_OF_RANGE_SHORT_BLOCK;
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Check both HCR lengths
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword,
|
|
- SHORT lengthOfReorderedSpectralData,
|
|
- UINT *errorWord) {
|
|
- if (lengthOfReorderedSpectralData < lengthOfLongestCodeword) {
|
|
- *errorWord |= HCR_SI_LENGTHS_FAILURE;
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Decode (and adapt if necessary) the two HCR sideinfo
|
|
-components: 'reordered_spectral_data_length' and 'longest_codeword_length'
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-void CHcr_Read(HANDLE_FDK_BITSTREAM bs,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- const MP4_ELEMENT_ID globalHcrType) {
|
|
- SHORT lengOfReorderedSpectralData;
|
|
- SCHAR lengOfLongestCodeword;
|
|
-
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfReorderedSpectralData =
|
|
- 0;
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword = 0;
|
|
-
|
|
- /* ------- SI-Value No 1 ------- */
|
|
- lengOfReorderedSpectralData = FDKreadBits(bs, 14) + ERROR_LORSD;
|
|
- if (globalHcrType == ID_CPE) {
|
|
- if ((lengOfReorderedSpectralData >= 0) &&
|
|
- (lengOfReorderedSpectralData <= CPE_TOP_LENGTH)) {
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac
|
|
- .lenOfReorderedSpectralData =
|
|
- lengOfReorderedSpectralData; /* the decoded value is within range */
|
|
- } else {
|
|
- if (lengOfReorderedSpectralData > CPE_TOP_LENGTH) {
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac
|
|
- .lenOfReorderedSpectralData =
|
|
- CPE_TOP_LENGTH; /* use valid maximum */
|
|
- }
|
|
- }
|
|
- } else if (globalHcrType == ID_SCE || globalHcrType == ID_LFE ||
|
|
- globalHcrType == ID_CCE) {
|
|
- if ((lengOfReorderedSpectralData >= 0) &&
|
|
- (lengOfReorderedSpectralData <= SCE_TOP_LENGTH)) {
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac
|
|
- .lenOfReorderedSpectralData =
|
|
- lengOfReorderedSpectralData; /* the decoded value is within range */
|
|
- } else {
|
|
- if (lengOfReorderedSpectralData > SCE_TOP_LENGTH) {
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac
|
|
- .lenOfReorderedSpectralData =
|
|
- SCE_TOP_LENGTH; /* use valid maximum */
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- /* ------- SI-Value No 2 ------- */
|
|
- lengOfLongestCodeword = FDKreadBits(bs, 6) + ERROR_LOLC;
|
|
- if ((lengOfLongestCodeword >= 0) &&
|
|
- (lengOfLongestCodeword <= LEN_OF_LONGEST_CW_TOP_LENGTH)) {
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword =
|
|
- lengOfLongestCodeword; /* the decoded value is within range */
|
|
- } else {
|
|
- if (lengOfLongestCodeword > LEN_OF_LONGEST_CW_TOP_LENGTH) {
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword =
|
|
- LEN_OF_LONGEST_CW_TOP_LENGTH; /* use valid maximum */
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Set up HCR - must be called before every call to
|
|
-HcrDecoder(). For short block a sorting algorithm is applied to get the SI in
|
|
-the order that HCR could assemble the qsc's as if it is a long block.
|
|
------------------------------------------------------------------------------------------------
|
|
- return: error log
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-UINT HcrInit(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- const SamplingRateInfo *pSamplingRateInfo,
|
|
- HANDLE_FDK_BITSTREAM bs) {
|
|
- CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
|
|
- SHORT *pNumLinesInSec;
|
|
- UCHAR *pCodeBk;
|
|
- SHORT numSection;
|
|
- SCHAR cb;
|
|
- int numLine;
|
|
- int i;
|
|
-
|
|
- pHcr->decInOut.lengthOfReorderedSpectralData =
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac
|
|
- .lenOfReorderedSpectralData;
|
|
- pHcr->decInOut.lengthOfLongestCodeword =
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword;
|
|
- pHcr->decInOut.pQuantizedSpectralCoefficientsBase =
|
|
- pAacDecoderChannelInfo->pSpectralCoefficient;
|
|
- pHcr->decInOut.quantizedSpectralCoefficientsIdx = 0;
|
|
- pHcr->decInOut.pCodebook =
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr;
|
|
- pHcr->decInOut.pNumLineInSect =
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr;
|
|
- pHcr->decInOut.numSection =
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection;
|
|
- pHcr->decInOut.errorLog = 0;
|
|
- pHcr->nonPcwSideinfo.pResultBase =
|
|
- SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
|
|
-
|
|
- FDKsyncCache(bs);
|
|
- pHcr->decInOut.bitstreamAnchor = (INT)FDKgetValidBits(bs);
|
|
-
|
|
- if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) /* short block */
|
|
- {
|
|
- SHORT band;
|
|
- SHORT maxBand;
|
|
- SCHAR group;
|
|
- SCHAR winGroupLen;
|
|
- SCHAR window;
|
|
- SCHAR numUnitInBand;
|
|
- SCHAR cntUnitInBand;
|
|
- SCHAR groupWin;
|
|
- SCHAR cb_prev;
|
|
-
|
|
- UCHAR *pCodeBook;
|
|
- const SHORT *BandOffsets;
|
|
- SCHAR numOfGroups;
|
|
-
|
|
- pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook; /* in */
|
|
- pNumLinesInSec = pHcr->decInOut.pNumLineInSect; /* out */
|
|
- pCodeBk = pHcr->decInOut.pCodebook; /* out */
|
|
- BandOffsets =
|
|
- GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo); /* aux */
|
|
- numOfGroups = GetWindowGroups(pIcsInfo);
|
|
-
|
|
- numLine = 0;
|
|
- numSection = 0;
|
|
- cb = pCodeBook[0];
|
|
- cb_prev = pCodeBook[0];
|
|
-
|
|
- /* convert HCR-sideinfo into a unitwise manner: When the cb changes, a new
|
|
- * section starts */
|
|
-
|
|
- *pCodeBk++ = cb_prev;
|
|
-
|
|
- maxBand = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
|
|
- for (band = 0; band < maxBand;
|
|
- band++) { /* from low to high sfbs i.e. from low to high frequencies */
|
|
- numUnitInBand =
|
|
- ((BandOffsets[band + 1] - BandOffsets[band]) >>
|
|
- FOUR_LOG_DIV_TWO_LOG); /* get the number of units in current sfb */
|
|
- for (cntUnitInBand = numUnitInBand; cntUnitInBand != 0;
|
|
- cntUnitInBand--) { /* for every unit in the band */
|
|
- for (window = 0, group = 0; group < numOfGroups; group++) {
|
|
- winGroupLen = (SCHAR)GetWindowGroupLength(
|
|
- &pAacDecoderChannelInfo->icsInfo, group);
|
|
- for (groupWin = winGroupLen; groupWin != 0; groupWin--, window++) {
|
|
- cb = pCodeBook[group * 16 + band];
|
|
- if (cb != cb_prev) {
|
|
- errDetectorInHcrSideinfoShrt(cb, numLine,
|
|
- &pHcr->decInOut.errorLog);
|
|
- if (pHcr->decInOut.errorLog != 0) {
|
|
- return (pHcr->decInOut.errorLog);
|
|
- }
|
|
- *pCodeBk++ = cb;
|
|
- *pNumLinesInSec++ = numLine;
|
|
- numSection++;
|
|
-
|
|
- cb_prev = cb;
|
|
- numLine = LINES_PER_UNIT;
|
|
- } else {
|
|
- numLine += LINES_PER_UNIT;
|
|
- }
|
|
- }
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- numSection++;
|
|
-
|
|
- errDetectorInHcrSideinfoShrt(cb, numLine, &pHcr->decInOut.errorLog);
|
|
- if (numSection <= 0 || numSection > 1024 / 2) {
|
|
- pHcr->decInOut.errorLog |= NUM_SECT_OUT_OF_RANGE_SHORT_BLOCK;
|
|
- }
|
|
- errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword,
|
|
- pHcr->decInOut.lengthOfReorderedSpectralData,
|
|
- &pHcr->decInOut.errorLog);
|
|
- if (pHcr->decInOut.errorLog != 0) {
|
|
- return (pHcr->decInOut.errorLog);
|
|
- }
|
|
-
|
|
- *pCodeBk = cb;
|
|
- *pNumLinesInSec = numLine;
|
|
- pHcr->decInOut.numSection = numSection;
|
|
-
|
|
- } else /* end short block prepare SI */
|
|
- { /* long block */
|
|
- errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword,
|
|
- pHcr->decInOut.lengthOfReorderedSpectralData,
|
|
- &pHcr->decInOut.errorLog);
|
|
- numSection = pHcr->decInOut.numSection;
|
|
- pNumLinesInSec = pHcr->decInOut.pNumLineInSect;
|
|
- pCodeBk = pHcr->decInOut.pCodebook;
|
|
- if (numSection <= 0 || numSection > 64) {
|
|
- pHcr->decInOut.errorLog |= NUM_SECT_OUT_OF_RANGE_LONG_BLOCK;
|
|
- numSection = 0;
|
|
- }
|
|
-
|
|
- for (i = numSection; i != 0; i--) {
|
|
- cb = *pCodeBk++;
|
|
-
|
|
- if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL) {
|
|
- pHcr->decInOut.errorLog |= CB_OUT_OF_RANGE_LONG_BLOCK;
|
|
- }
|
|
-
|
|
- numLine = *pNumLinesInSec++;
|
|
- /* FDK_ASSERT(numLine > 0); */
|
|
-
|
|
- if ((numLine <= 0) || (numLine > 1024)) {
|
|
- pHcr->decInOut.errorLog |= LINE_IN_SECT_OUT_OF_RANGE_LONG_BLOCK;
|
|
- }
|
|
- }
|
|
- if (pHcr->decInOut.errorLog != 0) {
|
|
- return (pHcr->decInOut.errorLog);
|
|
- }
|
|
- }
|
|
-
|
|
- pCodeBk = pHcr->decInOut.pCodebook;
|
|
- for (i = 0; i < numSection; i++) {
|
|
- if ((*pCodeBk == NOISE_HCB) || (*pCodeBk == INTENSITY_HCB2) ||
|
|
- (*pCodeBk == INTENSITY_HCB)) {
|
|
- *pCodeBk = 0;
|
|
- }
|
|
- pCodeBk++;
|
|
- }
|
|
-
|
|
- /* HCR-sideinfo-input is complete and seems to be valid */
|
|
-
|
|
- return (pHcr->decInOut.errorLog);
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function decodes the codewords of the spectral
|
|
-coefficients from the bitstream according to the HCR algorithm and stores the
|
|
-quantized spectral coefficients in correct order in the output buffer.
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-UINT HcrDecoder(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- const SamplingRateInfo *pSamplingRateInfo,
|
|
- HANDLE_FDK_BITSTREAM bs) {
|
|
- int pTmp1, pTmp2, pTmp3, pTmp4;
|
|
- int pTmp5;
|
|
-
|
|
- INT bitCntOffst;
|
|
- INT saveBitCnt = (INT)FDKgetValidBits(bs); /* save bitstream position */
|
|
-
|
|
- HcrCalcNumCodeword(pHcr);
|
|
-
|
|
- HcrSortCodebookAndNumCodewordInSection(pHcr);
|
|
-
|
|
- HcrPrepareSegmentationGrid(pHcr);
|
|
-
|
|
- HcrExtendedSectionInfo(pHcr);
|
|
-
|
|
- if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) != 0) {
|
|
- return (pHcr->decInOut.errorLog); /* sideinfo is massively corrupt, return
|
|
- from HCR without having decoded
|
|
- anything */
|
|
- }
|
|
-
|
|
- DeriveNumberOfExtendedSortedSectionsInSets(
|
|
- pHcr->segmentInfo.numSegment,
|
|
- pHcr->sectionInfo.pNumExtendedSortedCodewordInSection,
|
|
- pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx,
|
|
- pHcr->sectionInfo.pNumExtendedSortedSectionsInSets,
|
|
- pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx);
|
|
-
|
|
- /* store */
|
|
- pTmp1 = pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
|
|
- pTmp2 = pHcr->sectionInfo.extendedSortedCodebookIdx;
|
|
- pTmp3 = pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
|
|
- pTmp4 = pHcr->decInOut.quantizedSpectralCoefficientsIdx;
|
|
- pTmp5 = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx;
|
|
-
|
|
- /* ------- decode meaningful PCWs ------ */
|
|
- DecodePCWs(bs, pHcr);
|
|
-
|
|
- if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) == 0) {
|
|
- /* ------ decode the non-PCWs -------- */
|
|
- DecodeNonPCWs(bs, pHcr);
|
|
- }
|
|
-
|
|
- errDetectWithinSegmentationFinal(pHcr);
|
|
-
|
|
- /* restore */
|
|
- pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = pTmp1;
|
|
- pHcr->sectionInfo.extendedSortedCodebookIdx = pTmp2;
|
|
- pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = pTmp3;
|
|
- pHcr->decInOut.quantizedSpectralCoefficientsIdx = pTmp4;
|
|
- pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = pTmp5;
|
|
-
|
|
- HcrReorderQuantizedSpectralCoefficients(pHcr, pAacDecoderChannelInfo,
|
|
- pSamplingRateInfo);
|
|
-
|
|
- /* restore bitstream position */
|
|
- bitCntOffst = (INT)FDKgetValidBits(bs) - saveBitCnt;
|
|
- if (bitCntOffst) {
|
|
- FDKpushBiDirectional(bs, bitCntOffst);
|
|
- }
|
|
-
|
|
- return (pHcr->decInOut.errorLog);
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function reorders the quantized spectral coefficients
|
|
-sectionwise for long- and short-blocks and compares to the LAV (Largest Absolute
|
|
-Value of the current codebook) -- a counter is incremented if there is an error
|
|
- detected.
|
|
- Additional for short-blocks a unit-based-deinterleaving is
|
|
-applied. Moreover (for short blocks) the scaling is derived (compare plain
|
|
-huffman decoder).
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void HcrReorderQuantizedSpectralCoefficients(
|
|
- H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- const SamplingRateInfo *pSamplingRateInfo) {
|
|
- INT qsc;
|
|
- UINT abs_qsc;
|
|
- UINT i, j;
|
|
- USHORT numSpectralValuesInSection;
|
|
- FIXP_DBL *pTeVa;
|
|
- USHORT lavErrorCnt = 0;
|
|
-
|
|
- UINT numSection = pHcr->decInOut.numSection;
|
|
- SPECTRAL_PTR pQuantizedSpectralCoefficientsBase =
|
|
- pHcr->decInOut.pQuantizedSpectralCoefficientsBase;
|
|
- FIXP_DBL *pQuantizedSpectralCoefficients =
|
|
- SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase);
|
|
- const UCHAR *pCbDimShift = aDimCbShift;
|
|
- const USHORT *pLargestAbsVal = aLargestAbsoluteValue;
|
|
- UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
|
|
- USHORT *pNumSortedCodewordInSection =
|
|
- pHcr->sectionInfo.pNumSortedCodewordInSection;
|
|
- USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset;
|
|
- FIXP_DBL pTempValues[1024];
|
|
- FIXP_DBL *pBak = pTempValues;
|
|
-
|
|
- FDKmemclear(pTempValues, 1024 * sizeof(FIXP_DBL));
|
|
-
|
|
- /* long and short: check if decoded huffman-values (quantized spectral
|
|
- * coefficients) are within range */
|
|
- for (i = numSection; i != 0; i--) {
|
|
- numSpectralValuesInSection = *pNumSortedCodewordInSection++
|
|
- << pCbDimShift[*pSortedCodebook];
|
|
- pTeVa = &pTempValues[*pReorderOffset++];
|
|
- for (j = numSpectralValuesInSection; j != 0; j--) {
|
|
- qsc = *pQuantizedSpectralCoefficients++;
|
|
- abs_qsc = fAbs(qsc);
|
|
- if (abs_qsc <= pLargestAbsVal[*pSortedCodebook]) {
|
|
- *pTeVa++ = (FIXP_DBL)qsc; /* the qsc value is within range */
|
|
- } else { /* line is too high .. */
|
|
- if (abs_qsc ==
|
|
- Q_VALUE_INVALID) { /* .. because of previous marking --> dont set
|
|
- LAV flag (would be confusing), just copy out
|
|
- the already marked value */
|
|
- *pTeVa++ = (FIXP_DBL)qsc;
|
|
- } else { /* .. because a too high value was decoded for this cb --> set
|
|
- LAV flag */
|
|
- *pTeVa++ = (FIXP_DBL)Q_VALUE_INVALID;
|
|
- lavErrorCnt += 1;
|
|
- }
|
|
- }
|
|
- }
|
|
- pSortedCodebook++;
|
|
- }
|
|
-
|
|
- if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) {
|
|
- FIXP_DBL *pOut;
|
|
- FIXP_DBL locMax;
|
|
- FIXP_DBL tmp;
|
|
- SCHAR groupoffset;
|
|
- SCHAR group;
|
|
- SCHAR band;
|
|
- SCHAR groupwin;
|
|
- SCHAR window;
|
|
- SCHAR numWinGroup;
|
|
- SHORT interm;
|
|
- SCHAR numSfbTransm;
|
|
- SCHAR winGroupLen;
|
|
- SHORT index;
|
|
- INT msb;
|
|
- INT lsb;
|
|
-
|
|
- SHORT *pScaleFacHcr = pAacDecoderChannelInfo->pDynData->aScaleFactor;
|
|
- SHORT *pSfbSclHcr = pAacDecoderChannelInfo->pDynData->aSfbScale;
|
|
- const SHORT *BandOffsets = GetScaleFactorBandOffsets(
|
|
- &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
|
|
-
|
|
- pBak = pTempValues;
|
|
- /* deinterleave unitwise for short blocks */
|
|
- for (window = 0; window < (8); window++) {
|
|
- pOut = SPEC(pQuantizedSpectralCoefficientsBase, window,
|
|
- pAacDecoderChannelInfo->granuleLength);
|
|
- for (i = 0; i < (LINES_PER_UNIT_GROUP); i++) {
|
|
- pTeVa = pBak + (window << FOUR_LOG_DIV_TWO_LOG) +
|
|
- i * 32; /* distance of lines between unit groups has to be
|
|
- constant for every framelength (32)! */
|
|
- for (j = (LINES_PER_UNIT); j != 0; j--) {
|
|
- *pOut++ = *pTeVa++;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- /* short blocks only */
|
|
- /* derive global scaling-value for every sfb and every window (as it is done
|
|
- * in plain-huffman-decoder at short blocks) */
|
|
- groupoffset = 0;
|
|
-
|
|
- numWinGroup = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
|
|
- numSfbTransm =
|
|
- GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
|
|
-
|
|
- for (group = 0; group < numWinGroup; group++) {
|
|
- winGroupLen =
|
|
- GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
|
|
- for (band = 0; band < numSfbTransm; band++) {
|
|
- interm = group * 16 + band;
|
|
- msb = pScaleFacHcr[interm] >> 2;
|
|
- lsb = pScaleFacHcr[interm] & 3;
|
|
- for (groupwin = 0; groupwin < winGroupLen; groupwin++) {
|
|
- window = groupoffset + groupwin;
|
|
- pBak = SPEC(pQuantizedSpectralCoefficientsBase, window,
|
|
- pAacDecoderChannelInfo->granuleLength);
|
|
- locMax = FL2FXCONST_DBL(0.0f);
|
|
- for (index = BandOffsets[band]; index < BandOffsets[band + 1];
|
|
- index += LINES_PER_UNIT) {
|
|
- pTeVa = &pBak[index];
|
|
- for (i = LINES_PER_UNIT; i != 0; i--) {
|
|
- tmp = (*pTeVa < FL2FXCONST_DBL(0.0f)) ? -*pTeVa++ : *pTeVa++;
|
|
- locMax = fixMax(tmp, locMax);
|
|
- }
|
|
- }
|
|
- if (fixp_abs(locMax) > (FIXP_DBL)MAX_QUANTIZED_VALUE) {
|
|
- locMax = (FIXP_DBL)MAX_QUANTIZED_VALUE;
|
|
- }
|
|
- pSfbSclHcr[window * 16 + band] =
|
|
- msb - GetScaleFromValue(
|
|
- locMax, lsb); /* save global scale maxima in this sfb */
|
|
- }
|
|
- }
|
|
- groupoffset +=
|
|
- GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
|
|
- }
|
|
- } else {
|
|
- /* copy straight for long-blocks */
|
|
- pQuantizedSpectralCoefficients =
|
|
- SPEC_LONG(pQuantizedSpectralCoefficientsBase);
|
|
- for (i = 1024; i != 0; i--) {
|
|
- *pQuantizedSpectralCoefficients++ = *pBak++;
|
|
- }
|
|
- }
|
|
-
|
|
- if (lavErrorCnt != 0) {
|
|
- pHcr->decInOut.errorLog |= LAV_VIOLATION;
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function calculates the number of codewords
|
|
- for each section (numCodewordInSection) and the number of
|
|
-codewords for all sections (numCodeword). For zero and intensity codebooks a
|
|
-entry is also done in the variable numCodewordInSection. It is assumed that the
|
|
-codebook is a two tuples codebook. This is needed later for the calculation of
|
|
-the base addresses for the reordering of the quantize spectral coefficients at
|
|
-the end of the hcr tool. The variable numCodeword contain the number of
|
|
-codewords which are really in the bitstream. Zero or intensity codebooks does
|
|
-not increase the variable numCodewords.
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void HcrCalcNumCodeword(H_HCR_INFO pHcr) {
|
|
- int hcrSection;
|
|
- UINT numCodeword;
|
|
-
|
|
- UINT numSection = pHcr->decInOut.numSection;
|
|
- UCHAR *pCodebook = pHcr->decInOut.pCodebook;
|
|
- SHORT *pNumLineInSection = pHcr->decInOut.pNumLineInSect;
|
|
- const UCHAR *pCbDimShift = aDimCbShift;
|
|
-
|
|
- USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection;
|
|
-
|
|
- numCodeword = 0;
|
|
- for (hcrSection = numSection; hcrSection != 0; hcrSection--) {
|
|
- *pNumCodewordInSection = *pNumLineInSection++ >> pCbDimShift[*pCodebook];
|
|
- if (*pCodebook != 0) {
|
|
- numCodeword += *pNumCodewordInSection;
|
|
- }
|
|
- pNumCodewordInSection++;
|
|
- pCodebook++;
|
|
- }
|
|
- pHcr->sectionInfo.numCodeword = numCodeword;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function calculates the number
|
|
- of sorted codebooks and sorts the codebooks and the
|
|
-numCodewordInSection according to the priority.
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr) {
|
|
- UINT i, j, k;
|
|
- UCHAR temp;
|
|
- UINT counter;
|
|
- UINT startOffset;
|
|
- UINT numZeroSection;
|
|
- UCHAR *pDest;
|
|
- UINT numSectionDec;
|
|
-
|
|
- UINT numSection = pHcr->decInOut.numSection;
|
|
- UCHAR *pCodebook = pHcr->decInOut.pCodebook;
|
|
- UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
|
|
- USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection;
|
|
- USHORT *pNumSortedCodewordInSection =
|
|
- pHcr->sectionInfo.pNumSortedCodewordInSection;
|
|
- UCHAR *pCodebookSwitch = pHcr->sectionInfo.pCodebookSwitch;
|
|
- USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset;
|
|
- const UCHAR *pCbPriority = aCbPriority;
|
|
- const UCHAR *pMinOfCbPair = aMinOfCbPair;
|
|
- const UCHAR *pMaxOfCbPair = aMaxOfCbPair;
|
|
- const UCHAR *pCbDimShift = aDimCbShift;
|
|
-
|
|
- UINT searchStart = 0;
|
|
-
|
|
- /* calculate *pNumSortedSection and store the priorities in array
|
|
- * pSortedCdebook */
|
|
- pDest = pSortedCodebook;
|
|
- numZeroSection = 0;
|
|
- for (i = numSection; i != 0; i--) {
|
|
- if (pCbPriority[*pCodebook] == 0) {
|
|
- numZeroSection += 1;
|
|
- }
|
|
- *pDest++ = pCbPriority[*pCodebook++];
|
|
- }
|
|
- pHcr->sectionInfo.numSortedSection =
|
|
- numSection - numZeroSection; /* numSortedSection contains no zero or
|
|
- intensity section */
|
|
- pCodebook = pHcr->decInOut.pCodebook;
|
|
-
|
|
- /* sort priorities of the codebooks in array pSortedCdebook[] */
|
|
- numSectionDec = numSection - 1;
|
|
- if (numSectionDec > 0) {
|
|
- counter = numSectionDec;
|
|
- for (j = numSectionDec; j != 0; j--) {
|
|
- for (i = 0; i < counter; i++) {
|
|
- /* swap priorities */
|
|
- if (pSortedCodebook[i + 1] > pSortedCodebook[i]) {
|
|
- temp = pSortedCodebook[i];
|
|
- pSortedCodebook[i] = pSortedCodebook[i + 1];
|
|
- pSortedCodebook[i + 1] = temp;
|
|
- }
|
|
- }
|
|
- counter -= 1;
|
|
- }
|
|
- }
|
|
-
|
|
- /* clear codebookSwitch array */
|
|
- for (i = numSection; i != 0; i--) {
|
|
- *pCodebookSwitch++ = 0;
|
|
- }
|
|
- pCodebookSwitch = pHcr->sectionInfo.pCodebookSwitch;
|
|
-
|
|
- /* sort sectionCodebooks and numCodwordsInSection and calculate
|
|
- * pReorderOffst[j] */
|
|
- for (j = 0; j < numSection; j++) {
|
|
- for (i = searchStart; i < numSection; i++) {
|
|
- if (pCodebookSwitch[i] == 0 &&
|
|
- (pMinOfCbPair[pSortedCodebook[j]] == pCodebook[i] ||
|
|
- pMaxOfCbPair[pSortedCodebook[j]] == pCodebook[i])) {
|
|
- pCodebookSwitch[i] = 1;
|
|
- pSortedCodebook[j] = pCodebook[i]; /* sort codebook */
|
|
- pNumSortedCodewordInSection[j] =
|
|
- pNumCodewordInSection[i]; /* sort NumCodewordInSection */
|
|
-
|
|
- startOffset = 0;
|
|
- for (k = 0; k < i; k++) { /* make entry in pReorderOffst */
|
|
- startOffset += pNumCodewordInSection[k] << pCbDimShift[pCodebook[k]];
|
|
- }
|
|
- pReorderOffset[j] =
|
|
- startOffset; /* offset for reordering the codewords */
|
|
-
|
|
- if (i == searchStart) {
|
|
- k = i;
|
|
- while (pCodebookSwitch[k++] == 1) searchStart++;
|
|
- }
|
|
- break;
|
|
- }
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function calculates the segmentation, which includes
|
|
-numSegment, leftStartOfSegment, rightStartOfSegment and remainingBitsInSegment.
|
|
- The segmentation could be visualized a as kind of
|
|
-'overlay-grid' for the bitstream-block holding the HCR-encoded
|
|
-quantized-spectral-coefficients.
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr) {
|
|
- USHORT i, j;
|
|
- USHORT numSegment = 0;
|
|
- INT segmentStart = 0;
|
|
- UCHAR segmentWidth;
|
|
- UCHAR lastSegmentWidth;
|
|
- UCHAR sortedCodebook;
|
|
- UCHAR endFlag = 0;
|
|
- INT intermediateResult;
|
|
-
|
|
- SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword;
|
|
- SHORT lengthOfReorderedSpectralData =
|
|
- pHcr->decInOut.lengthOfReorderedSpectralData;
|
|
- UINT numSortedSection = pHcr->sectionInfo.numSortedSection;
|
|
- UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
|
|
- USHORT *pNumSortedCodewordInSection =
|
|
- pHcr->sectionInfo.pNumSortedCodewordInSection;
|
|
- INT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
|
|
- INT *pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
|
|
- SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
|
|
- const UCHAR *pMaxCwLength = aMaxCwLen;
|
|
-
|
|
- for (i = numSortedSection; i != 0; i--) {
|
|
- sortedCodebook = *pSortedCodebook++;
|
|
- segmentWidth =
|
|
- fMin((INT)pMaxCwLength[sortedCodebook], (INT)lengthOfLongestCodeword);
|
|
-
|
|
- for (j = *pNumSortedCodewordInSection; j != 0; j--) {
|
|
- /* width allows a new segment */
|
|
- intermediateResult = segmentStart;
|
|
- if ((segmentStart + segmentWidth) <= lengthOfReorderedSpectralData) {
|
|
- /* store segment start, segment length and increment the number of
|
|
- * segments */
|
|
- *pLeftStartOfSegment++ = intermediateResult;
|
|
- *pRightStartOfSegment++ = intermediateResult + segmentWidth - 1;
|
|
- *pRemainingBitsInSegment++ = segmentWidth;
|
|
- segmentStart += segmentWidth;
|
|
- numSegment += 1;
|
|
- }
|
|
- /* width does not allow a new segment */
|
|
- else {
|
|
- /* correct the last segment length */
|
|
- pLeftStartOfSegment--;
|
|
- pRightStartOfSegment--;
|
|
- pRemainingBitsInSegment--;
|
|
- segmentStart = *pLeftStartOfSegment;
|
|
-
|
|
- lastSegmentWidth = lengthOfReorderedSpectralData - segmentStart;
|
|
- *pRemainingBitsInSegment = lastSegmentWidth;
|
|
- *pRightStartOfSegment = segmentStart + lastSegmentWidth - 1;
|
|
- endFlag = 1;
|
|
- break;
|
|
- }
|
|
- }
|
|
- pNumSortedCodewordInSection++;
|
|
- if (endFlag != 0) {
|
|
- break;
|
|
- }
|
|
- }
|
|
- pHcr->segmentInfo.numSegment = numSegment;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function adapts the sorted section boundaries to the
|
|
-boundaries of segmentation. If the section lengths does not fit completely into
|
|
-the current segment, the section is spitted into two so called 'extended
|
|
- sections'. The extended-section-info
|
|
-(pNumExtendedSortedCodewordInSectin and pExtendedSortedCodebook) is updated in
|
|
-this case.
|
|
-
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void HcrExtendedSectionInfo(H_HCR_INFO pHcr) {
|
|
- UINT srtSecCnt = 0; /* counter for sorted sections */
|
|
- UINT xSrtScCnt = 0; /* counter for extended sorted sections */
|
|
- UINT remainNumCwInSortSec;
|
|
- UINT inSegmentRemainNumCW;
|
|
-
|
|
- UINT numSortedSection = pHcr->sectionInfo.numSortedSection;
|
|
- UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
|
|
- USHORT *pNumSortedCodewordInSection =
|
|
- pHcr->sectionInfo.pNumSortedCodewordInSection;
|
|
- UCHAR *pExtendedSortedCoBo = pHcr->sectionInfo.pExtendedSortedCodebook;
|
|
- USHORT *pNumExtSortCwInSect =
|
|
- pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
|
|
- UINT numSegment = pHcr->segmentInfo.numSegment;
|
|
- UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec;
|
|
- SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword;
|
|
- const UCHAR *pMaxCwLength = aMaxCwLen;
|
|
-
|
|
- remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
|
|
- inSegmentRemainNumCW = numSegment;
|
|
-
|
|
- while (srtSecCnt < numSortedSection) {
|
|
- if (inSegmentRemainNumCW < remainNumCwInSortSec) {
|
|
- pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW;
|
|
- pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
|
|
-
|
|
- remainNumCwInSortSec -= inSegmentRemainNumCW;
|
|
- inSegmentRemainNumCW = numSegment;
|
|
- /* data of a sorted section was not integrated in extended sorted section
|
|
- */
|
|
- } else if (inSegmentRemainNumCW == remainNumCwInSortSec) {
|
|
- pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW;
|
|
- pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
|
|
-
|
|
- srtSecCnt++;
|
|
- remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
|
|
- inSegmentRemainNumCW = numSegment;
|
|
- /* data of a sorted section was integrated in extended sorted section */
|
|
- } else { /* inSegmentRemainNumCW > remainNumCwInSortSec */
|
|
- pNumExtSortCwInSect[xSrtScCnt] = remainNumCwInSortSec;
|
|
- pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
|
|
-
|
|
- inSegmentRemainNumCW -= remainNumCwInSortSec;
|
|
- srtSecCnt++;
|
|
- remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
|
|
- /* data of a sorted section was integrated in extended sorted section */
|
|
- }
|
|
- pMaxLenOfCbInExtSrtSec[xSrtScCnt] =
|
|
- fMin((INT)pMaxCwLength[pExtendedSortedCoBo[xSrtScCnt]],
|
|
- (INT)lengthOfLongestCodeword);
|
|
-
|
|
- xSrtScCnt += 1;
|
|
-
|
|
- if (xSrtScCnt >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
|
|
- pHcr->decInOut.errorLog |= EXTENDED_SORTED_COUNTER_OVERFLOW;
|
|
- return;
|
|
- }
|
|
- }
|
|
- pNumExtSortCwInSect[xSrtScCnt] = 0;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function calculates the number of extended sorted
|
|
-sections which belong to the sets. Each set from set 0 (one and only set for the
|
|
-PCWs) till to the last set gets a entry in the array to which
|
|
- 'pNumExtendedSortedSectinsInSets' points to.
|
|
-
|
|
- Calculation: The entrys in
|
|
-pNumExtendedSortedCodewordInSectin are added untill the value numSegment is
|
|
-reached. Then the sum_variable is cleared and the calculation starts from the
|
|
-beginning. As much extended sorted Sections are summed up to reach the value
|
|
-numSegment, as much is the current entry in *pNumExtendedSortedCodewordInSectin.
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-static void DeriveNumberOfExtendedSortedSectionsInSets(
|
|
- UINT numSegment, USHORT *pNumExtendedSortedCodewordInSection,
|
|
- int numExtendedSortedCodewordInSectionIdx,
|
|
- USHORT *pNumExtendedSortedSectionsInSets,
|
|
- int numExtendedSortedSectionsInSetsIdx) {
|
|
- USHORT counter = 0;
|
|
- UINT cwSum = 0;
|
|
- USHORT *pNumExSortCwInSec = pNumExtendedSortedCodewordInSection;
|
|
- USHORT *pNumExSortSecInSets = pNumExtendedSortedSectionsInSets;
|
|
-
|
|
- while (pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx] != 0) {
|
|
- cwSum += pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx];
|
|
- numExtendedSortedCodewordInSectionIdx++;
|
|
- if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
|
|
- return;
|
|
- }
|
|
- if (cwSum > numSegment) {
|
|
- return;
|
|
- }
|
|
- counter++;
|
|
- if (counter > 1024 / 4) {
|
|
- return;
|
|
- }
|
|
- if (cwSum == numSegment) {
|
|
- pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] = counter;
|
|
- numExtendedSortedSectionsInSetsIdx++;
|
|
- if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) {
|
|
- return;
|
|
- }
|
|
- counter = 0;
|
|
- cwSum = 0;
|
|
- }
|
|
- }
|
|
- pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] =
|
|
- counter; /* save last entry for the last - probably shorter - set */
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function decodes all priority codewords (PCWs) in a
|
|
-spectrum (within set 0). The calculation of the PCWs is managed in two loops.
|
|
-The loopcounter of the outer loop is set to the first value pointer
|
|
- pNumExtendedSortedSectionsInSets points to. This value
|
|
-represents the number of extended sorted sections within set 0. The loopcounter
|
|
-of the inner loop is set to the first value pointer
|
|
- pNumExtendedSortedCodewordInSectin points to. The value
|
|
-represents the number of extended sorted codewords in sections (the original
|
|
-sections have been splitted to go along with the borders of the sets). Each time
|
|
-the number of the extended sorted codewords in sections are de- coded, the
|
|
-pointer 'pNumExtendedSortedCodewordInSectin' is incremented by one.
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
|
|
- UINT i;
|
|
- USHORT extSortSec;
|
|
- USHORT curExtSortCwInSec;
|
|
- UCHAR codebook;
|
|
- UCHAR dimension;
|
|
- const UINT *pCurrentTree;
|
|
- const SCHAR *pQuantValBase;
|
|
- const SCHAR *pQuantVal;
|
|
-
|
|
- USHORT *pNumExtendedSortedCodewordInSection =
|
|
- pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
|
|
- int numExtendedSortedCodewordInSectionIdx =
|
|
- pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
|
|
- UCHAR *pExtendedSortedCodebook = pHcr->sectionInfo.pExtendedSortedCodebook;
|
|
- int extendedSortedCodebookIdx = pHcr->sectionInfo.extendedSortedCodebookIdx;
|
|
- USHORT *pNumExtendedSortedSectionsInSets =
|
|
- pHcr->sectionInfo.pNumExtendedSortedSectionsInSets;
|
|
- int numExtendedSortedSectionsInSetsIdx =
|
|
- pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
|
|
- FIXP_DBL *pQuantizedSpectralCoefficients =
|
|
- SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase);
|
|
- int quantizedSpectralCoefficientsIdx =
|
|
- pHcr->decInOut.quantizedSpectralCoefficientsIdx;
|
|
- INT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
|
|
- SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
|
|
- UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec;
|
|
- int maxLenOfCbInExtSrtSecIdx = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx;
|
|
- UCHAR maxAllowedCwLen;
|
|
- int numDecodedBits;
|
|
- const UCHAR *pCbDimension = aDimCb;
|
|
- const UCHAR *pCbSign = aSignCb;
|
|
-
|
|
- /* clear result array */
|
|
- FDKmemclear(pQuantizedSpectralCoefficients + quantizedSpectralCoefficientsIdx,
|
|
- 1024 * sizeof(FIXP_DBL));
|
|
-
|
|
- /* decode all PCWs in the extended sorted section(s) belonging to set 0 */
|
|
- for (extSortSec =
|
|
- pNumExtendedSortedSectionsInSets[numExtendedSortedSectionsInSetsIdx];
|
|
- extSortSec != 0; extSortSec--) {
|
|
- codebook =
|
|
- pExtendedSortedCodebook[extendedSortedCodebookIdx]; /* get codebook for
|
|
- this extended
|
|
- sorted section
|
|
- and increment ptr
|
|
- to cb of next
|
|
- ext. sort sec */
|
|
- extendedSortedCodebookIdx++;
|
|
- if (extendedSortedCodebookIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
|
|
- return;
|
|
- }
|
|
- dimension = pCbDimension[codebook]; /* get dimension of codebook of this
|
|
- extended sort. sec. */
|
|
- pCurrentTree =
|
|
- aHuffTable[codebook]; /* convert codebook to pointer to QSCs */
|
|
- pQuantValBase =
|
|
- aQuantTable[codebook]; /* convert codebook to index to table of QSCs */
|
|
- maxAllowedCwLen = pMaxLenOfCbInExtSrtSec[maxLenOfCbInExtSrtSecIdx];
|
|
- maxLenOfCbInExtSrtSecIdx++;
|
|
- if (maxLenOfCbInExtSrtSecIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
|
|
- return;
|
|
- }
|
|
-
|
|
- /* switch for decoding with different codebooks: */
|
|
- if (pCbSign[codebook] ==
|
|
- 0) { /* no sign bits follow after the codeword-body */
|
|
- /* PCW_BodyONLY */
|
|
- /*==============*/
|
|
-
|
|
- for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
|
|
- [numExtendedSortedCodewordInSectionIdx];
|
|
- curExtSortCwInSec != 0; curExtSortCwInSec--) {
|
|
- numDecodedBits = 0;
|
|
-
|
|
- /* decode PCW_BODY */
|
|
- pQuantVal = DecodePCW_Body(
|
|
- bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
|
|
- pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
|
|
-
|
|
- /* result is written out here because NO sign bits follow the body */
|
|
- for (i = dimension; i != 0; i--) {
|
|
- pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
|
|
- (FIXP_DBL)*pQuantVal++; /* write quant. spec. coef. into
|
|
- spectrum; sign is already valid */
|
|
- quantizedSpectralCoefficientsIdx++;
|
|
- if (quantizedSpectralCoefficientsIdx >= 1024) {
|
|
- return;
|
|
- }
|
|
- }
|
|
-
|
|
- /* one more PCW should be decoded */
|
|
-
|
|
- if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_ONLY_TOO_LONG)) {
|
|
- pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_BITS_DECODED;
|
|
- }
|
|
-
|
|
- if (1 == errDetectPcwSegmentation(
|
|
- *pRemainingBitsInSegment - ERROR_PCW_BODY, pHcr, PCW_BODY,
|
|
- pQuantizedSpectralCoefficients +
|
|
- quantizedSpectralCoefficientsIdx - dimension,
|
|
- dimension)) {
|
|
- return;
|
|
- }
|
|
- pLeftStartOfSegment++; /* update pointer for decoding the next PCW */
|
|
- pRemainingBitsInSegment++; /* update pointer for decoding the next PCW
|
|
- */
|
|
- }
|
|
- } else if ((codebook < 11) && (pCbSign[codebook] ==
|
|
- 1)) { /* possibly there follow 1,2,3 or 4
|
|
- sign bits after the codeword-body */
|
|
- /* PCW_Body and PCW_Sign */
|
|
- /*=======================*/
|
|
-
|
|
- for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
|
|
- [numExtendedSortedCodewordInSectionIdx];
|
|
- curExtSortCwInSec != 0; curExtSortCwInSec--) {
|
|
- int err;
|
|
- numDecodedBits = 0;
|
|
-
|
|
- pQuantVal = DecodePCW_Body(
|
|
- bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
|
|
- pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
|
|
-
|
|
- err = DecodePCW_Sign(
|
|
- bs, pHcr->decInOut.bitstreamAnchor, dimension, pQuantVal,
|
|
- pQuantizedSpectralCoefficients, &quantizedSpectralCoefficientsIdx,
|
|
- pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
|
|
- if (err != 0) {
|
|
- return;
|
|
- }
|
|
- /* one more PCW should be decoded */
|
|
-
|
|
- if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_SIGN_TOO_LONG)) {
|
|
- pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_BITS_DECODED;
|
|
- }
|
|
-
|
|
- if (1 == errDetectPcwSegmentation(
|
|
- *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN, pHcr,
|
|
- PCW_BODY_SIGN,
|
|
- pQuantizedSpectralCoefficients +
|
|
- quantizedSpectralCoefficientsIdx - dimension,
|
|
- dimension)) {
|
|
- return;
|
|
- }
|
|
- pLeftStartOfSegment++;
|
|
- pRemainingBitsInSegment++;
|
|
- }
|
|
- } else if ((pCbSign[codebook] == 1) &&
|
|
- (codebook >= 11)) { /* possibly there follow some sign bits and
|
|
- maybe one or two escape sequences after
|
|
- the cw-body */
|
|
- /* PCW_Body, PCW_Sign and maybe PCW_Escape */
|
|
- /*=========================================*/
|
|
-
|
|
- for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
|
|
- [numExtendedSortedCodewordInSectionIdx];
|
|
- curExtSortCwInSec != 0; curExtSortCwInSec--) {
|
|
- int err;
|
|
- numDecodedBits = 0;
|
|
-
|
|
- /* decode PCW_BODY */
|
|
- pQuantVal = DecodePCW_Body(
|
|
- bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
|
|
- pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
|
|
-
|
|
- err = DecodePCW_Sign(
|
|
- bs, pHcr->decInOut.bitstreamAnchor, dimension, pQuantVal,
|
|
- pQuantizedSpectralCoefficients, &quantizedSpectralCoefficientsIdx,
|
|
- pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
|
|
- if (err != 0) {
|
|
- return;
|
|
- }
|
|
-
|
|
- /* decode PCW_ESCAPE if present */
|
|
- quantizedSpectralCoefficientsIdx -= DIMENSION_OF_ESCAPE_CODEBOOK;
|
|
-
|
|
- if (fixp_abs(pQuantizedSpectralCoefficients
|
|
- [quantizedSpectralCoefficientsIdx]) ==
|
|
- (FIXP_DBL)ESCAPE_VALUE) {
|
|
- pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
|
|
- (FIXP_DBL)DecodeEscapeSequence(
|
|
- bs, pHcr->decInOut.bitstreamAnchor,
|
|
- pQuantizedSpectralCoefficients
|
|
- [quantizedSpectralCoefficientsIdx],
|
|
- pLeftStartOfSegment, pRemainingBitsInSegment,
|
|
- &numDecodedBits);
|
|
- }
|
|
- quantizedSpectralCoefficientsIdx++;
|
|
- if (quantizedSpectralCoefficientsIdx >= 1024) {
|
|
- return;
|
|
- }
|
|
-
|
|
- if (fixp_abs(pQuantizedSpectralCoefficients
|
|
- [quantizedSpectralCoefficientsIdx]) ==
|
|
- (FIXP_DBL)ESCAPE_VALUE) {
|
|
- pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
|
|
- (FIXP_DBL)DecodeEscapeSequence(
|
|
- bs, pHcr->decInOut.bitstreamAnchor,
|
|
- pQuantizedSpectralCoefficients
|
|
- [quantizedSpectralCoefficientsIdx],
|
|
- pLeftStartOfSegment, pRemainingBitsInSegment,
|
|
- &numDecodedBits);
|
|
- }
|
|
- quantizedSpectralCoefficientsIdx++;
|
|
- if (quantizedSpectralCoefficientsIdx >= 1024) {
|
|
- return;
|
|
- }
|
|
-
|
|
- /* one more PCW should be decoded */
|
|
-
|
|
- if (maxAllowedCwLen <
|
|
- (numDecodedBits + ERROR_PCW_BODY_SIGN_ESC_TOO_LONG)) {
|
|
- pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED;
|
|
- }
|
|
-
|
|
- if (1 == errDetectPcwSegmentation(
|
|
- *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN_ESC, pHcr,
|
|
- PCW_BODY_SIGN_ESC,
|
|
- pQuantizedSpectralCoefficients +
|
|
- quantizedSpectralCoefficientsIdx -
|
|
- DIMENSION_OF_ESCAPE_CODEBOOK,
|
|
- DIMENSION_OF_ESCAPE_CODEBOOK)) {
|
|
- return;
|
|
- }
|
|
- pLeftStartOfSegment++;
|
|
- pRemainingBitsInSegment++;
|
|
- }
|
|
- }
|
|
-
|
|
- /* all PCWs belonging to this extended section should be decoded */
|
|
- numExtendedSortedCodewordInSectionIdx++;
|
|
- if (numExtendedSortedCodewordInSectionIdx >= MAX_SFB_HCR + MAX_HCR_SETS) {
|
|
- return;
|
|
- }
|
|
- }
|
|
- /* all PCWs should be decoded */
|
|
-
|
|
- numExtendedSortedSectionsInSetsIdx++;
|
|
- if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) {
|
|
- return;
|
|
- }
|
|
-
|
|
- /* Write back indexes into structure */
|
|
- pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
|
|
- numExtendedSortedCodewordInSectionIdx;
|
|
- pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx;
|
|
- pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx =
|
|
- numExtendedSortedSectionsInSetsIdx;
|
|
- pHcr->decInOut.quantizedSpectralCoefficientsIdx =
|
|
- quantizedSpectralCoefficientsIdx;
|
|
- pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = maxLenOfCbInExtSrtSecIdx;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function checks immediately after every decoded PCW,
|
|
-whether out of the current segment too many bits have been read or not. If an
|
|
-error occurrs, probably the sideinfo or the HCR-bitstream block holding the
|
|
-huffman encoded quantized spectral coefficients is distorted. In this case the
|
|
-two or four quantized spectral coefficients belonging to the current codeword
|
|
- are marked (for being detected by concealment later).
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment,
|
|
- H_HCR_INFO pHcr, PCW_TYPE kind,
|
|
- FIXP_DBL *qsc_base_of_cw,
|
|
- UCHAR dimension) {
|
|
- SCHAR i;
|
|
- if (remainingBitsInSegment < 0) {
|
|
- /* log the error */
|
|
- switch (kind) {
|
|
- case PCW_BODY:
|
|
- pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY;
|
|
- break;
|
|
- case PCW_BODY_SIGN:
|
|
- pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN;
|
|
- break;
|
|
- case PCW_BODY_SIGN_ESC:
|
|
- pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN_ESC;
|
|
- break;
|
|
- }
|
|
- /* mark the erred lines */
|
|
- for (i = dimension; i != 0; i--) {
|
|
- *qsc_base_of_cw++ = (FIXP_DBL)Q_VALUE_INVALID;
|
|
- }
|
|
- return 1;
|
|
- }
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function checks if all segments are empty after
|
|
-decoding. There are _no lines markded_ as invalid because it could not be traced
|
|
-back where from the remaining bits are.
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr) {
|
|
- UCHAR segmentationErrorFlag = 0;
|
|
- USHORT i;
|
|
- SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
|
|
- UINT numSegment = pHcr->segmentInfo.numSegment;
|
|
-
|
|
- for (i = numSegment; i != 0; i--) {
|
|
- if (*pRemainingBitsInSegment++ != 0) {
|
|
- segmentationErrorFlag = 1;
|
|
- }
|
|
- }
|
|
- if (segmentationErrorFlag == 1) {
|
|
- pHcr->decInOut.errorLog |= BIT_IN_SEGMENTATION_ERROR;
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function walks one step within the decoding tree. Which
|
|
-branch is taken depends on the decoded carryBit input parameter.
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-void CarryBitToBranchValue(UCHAR carryBit, UINT treeNode, UINT *branchValue,
|
|
- UINT *branchNode) {
|
|
- if (carryBit == 0) {
|
|
- *branchNode =
|
|
- (treeNode & MASK_LEFT) >> LEFT_OFFSET; /* MASK_LEFT: 00FFF000 */
|
|
- } else {
|
|
- *branchNode = treeNode & MASK_RIGHT; /* MASK_RIGHT: 00000FFF */
|
|
- }
|
|
-
|
|
- *branchValue = *branchNode & CLR_BIT_10; /* clear bit 10 (if set) */
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Decodes the body of a priority codeword (PCW)
|
|
------------------------------------------------------------------------------------------------
|
|
- return: - return value is pointer to first of two or four quantized
|
|
-spectral coefficients
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|
- const UINT *pCurrentTree,
|
|
- const SCHAR *pQuantValBase,
|
|
- INT *pLeftStartOfSegment,
|
|
- SCHAR *pRemainingBitsInSegment,
|
|
- int *pNumDecodedBits) {
|
|
- UCHAR carryBit;
|
|
- UINT branchNode;
|
|
- UINT treeNode;
|
|
- UINT branchValue;
|
|
- const SCHAR *pQuantVal;
|
|
-
|
|
- /* decode PCW_BODY */
|
|
- treeNode = *pCurrentTree; /* get first node of current tree belonging to
|
|
- current codebook */
|
|
-
|
|
- /* decode whole PCW-codeword-body */
|
|
- while (1) {
|
|
- carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
|
|
- pLeftStartOfSegment, /* dummy */
|
|
- FROM_LEFT_TO_RIGHT);
|
|
- *pRemainingBitsInSegment -= 1;
|
|
- *pNumDecodedBits += 1;
|
|
-
|
|
- CarryBitToBranchValue(carryBit, treeNode, &branchValue, &branchNode);
|
|
-
|
|
- if ((branchNode & TEST_BIT_10) ==
|
|
- TEST_BIT_10) { /* test bit 10 ; if set --> codeword-body is complete */
|
|
- break; /* end of branch in tree reached i.e. a whole PCW-Body is decoded
|
|
- */
|
|
- } else {
|
|
- treeNode = *(
|
|
- pCurrentTree +
|
|
- branchValue); /* update treeNode for further step in decoding tree */
|
|
- }
|
|
- }
|
|
-
|
|
- pQuantVal =
|
|
- pQuantValBase + branchValue; /* update pointer to valid first of 2 or 4
|
|
- quantized values */
|
|
-
|
|
- return pQuantVal;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function decodes one escape sequence. In case of a
|
|
-escape codebook and in case of the absolute value of the quantized spectral
|
|
-value == 16, a escapeSequence is decoded in two steps:
|
|
- 1. escape prefix
|
|
- 2. escape word
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|
- INT quantSpecCoef, INT *pLeftStartOfSegment,
|
|
- SCHAR *pRemainingBitsInSegment,
|
|
- int *pNumDecodedBits) {
|
|
- UINT i;
|
|
- INT sign;
|
|
- UINT escapeOnesCounter = 0;
|
|
- UINT carryBit;
|
|
- INT escape_word = 0;
|
|
-
|
|
- /* decode escape prefix */
|
|
- while (1) {
|
|
- carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
|
|
- pLeftStartOfSegment, /* dummy */
|
|
- FROM_LEFT_TO_RIGHT);
|
|
- *pRemainingBitsInSegment -= 1;
|
|
- *pNumDecodedBits += 1;
|
|
-
|
|
- if (carryBit != 0) {
|
|
- escapeOnesCounter += 1;
|
|
- } else {
|
|
- escapeOnesCounter += 4;
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- /* decode escape word */
|
|
- for (i = escapeOnesCounter; i != 0; i--) {
|
|
- carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
|
|
- pLeftStartOfSegment, /* dummy */
|
|
- FROM_LEFT_TO_RIGHT);
|
|
- *pRemainingBitsInSegment -= 1;
|
|
- *pNumDecodedBits += 1;
|
|
-
|
|
- escape_word <<= 1;
|
|
- escape_word = escape_word | carryBit;
|
|
- }
|
|
-
|
|
- sign = (quantSpecCoef >= 0) ? 1 : -1;
|
|
-
|
|
- quantSpecCoef = sign * (((INT)1 << escapeOnesCounter) + escape_word);
|
|
-
|
|
- return quantSpecCoef;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Decodes the Signbits of a priority codeword (PCW) and writes
|
|
-out the resulting quantized spectral values into unsorted sections
|
|
------------------------------------------------------------------------------------------------
|
|
- output: - two or four lines at position in corresponding section
|
|
-(which are not located at the desired position, i.e. they must be reordered in
|
|
-the last of eight function of HCR)
|
|
------------------------------------------------------------------------------------------------
|
|
- return: - updated pQuantSpecCoef pointer (to next empty storage for a
|
|
-line)
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|
- UINT codebookDim, const SCHAR *pQuantVal,
|
|
- FIXP_DBL *pQuantSpecCoef, int *quantSpecCoefIdx,
|
|
- INT *pLeftStartOfSegment,
|
|
- SCHAR *pRemainingBitsInSegment,
|
|
- int *pNumDecodedBits) {
|
|
- UINT i;
|
|
- UINT carryBit;
|
|
- INT quantSpecCoef;
|
|
-
|
|
- for (i = codebookDim; i != 0; i--) {
|
|
- quantSpecCoef = *pQuantVal++;
|
|
- if (quantSpecCoef != 0) {
|
|
- carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
|
|
- pLeftStartOfSegment, /* dummy */
|
|
- FROM_LEFT_TO_RIGHT);
|
|
- *pRemainingBitsInSegment -= 1;
|
|
- *pNumDecodedBits += 1;
|
|
- if (*pRemainingBitsInSegment < 0 || *pNumDecodedBits >= (1024 >> 1)) {
|
|
- return -1;
|
|
- }
|
|
-
|
|
- /* adapt sign of values according to the decoded sign bit */
|
|
- if (carryBit != 0) {
|
|
- pQuantSpecCoef[*quantSpecCoefIdx] = -(FIXP_DBL)quantSpecCoef;
|
|
- } else {
|
|
- pQuantSpecCoef[*quantSpecCoefIdx] = (FIXP_DBL)quantSpecCoef;
|
|
- }
|
|
- } else {
|
|
- pQuantSpecCoef[*quantSpecCoefIdx] = FL2FXCONST_DBL(0.0f);
|
|
- }
|
|
- *quantSpecCoefIdx += 1;
|
|
- if (*quantSpecCoefIdx >= 1024) {
|
|
- return -1;
|
|
- }
|
|
- }
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Mutes spectral lines which have been marked as erroneous
|
|
-(Q_VALUE_INVALID)
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-void HcrMuteErroneousLines(H_HCR_INFO hHcr) {
|
|
- int c;
|
|
- FIXP_DBL *RESTRICT pLong =
|
|
- SPEC_LONG(hHcr->decInOut.pQuantizedSpectralCoefficientsBase);
|
|
-
|
|
- /* if there is a line with value Q_VALUE_INVALID mute it */
|
|
- for (c = 0; c < 1024; c++) {
|
|
- if (pLong[c] == (FIXP_DBL)Q_VALUE_INVALID) {
|
|
- pLong[c] = FL2FXCONST_DBL(0.0f); /* muting */
|
|
- }
|
|
- }
|
|
-}
|
|
--- a/libAACdec/src/aacdec_hcr.h
|
|
+++ /dev/null
|
|
@@ -1,128 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s): Robert Weidner (DSP Solutions)
|
|
-
|
|
- Description: HCR Decoder: Interface function declaration; common defines
|
|
- and structures; defines for switching error-generator,
|
|
- -detector, and -concealment
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-#ifndef AACDEC_HCR_H
|
|
-#define AACDEC_HCR_H
|
|
-
|
|
-#include "channelinfo.h"
|
|
-#include "FDK_bitstream.h"
|
|
-
|
|
-UINT HcrInit(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- const SamplingRateInfo *pSamplingRateInfo,
|
|
- HANDLE_FDK_BITSTREAM bs);
|
|
-UINT HcrDecoder(H_HCR_INFO hHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- const SamplingRateInfo *pSamplingRateInfo,
|
|
- HANDLE_FDK_BITSTREAM bs);
|
|
-void CarryBitToBranchValue(UCHAR carryBit, UINT treeNode, UINT *branchValue,
|
|
- UINT *branchNode);
|
|
-
|
|
-void CHcr_Read(HANDLE_FDK_BITSTREAM bs,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- const MP4_ELEMENT_ID globalHcrType);
|
|
-void HcrMuteErroneousLines(H_HCR_INFO hHcr);
|
|
-
|
|
-void setHcrType(H_HCR_INFO hHcr, MP4_ELEMENT_ID type);
|
|
-INT getHcrType(H_HCR_INFO hHcr);
|
|
-
|
|
-#endif /* AACDEC_HCR_H */
|
|
--- a/libAACdec/src/aacdec_hcr_bit.cpp
|
|
+++ /dev/null
|
|
@@ -1,164 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s): Robert Weidner (DSP Solutions)
|
|
-
|
|
- Description: HCR Decoder: Bitstream reading
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-#include "aacdec_hcr_bit.h"
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function toggles the read direction.
|
|
------------------------------------------------------------------------------------------------
|
|
- input: current read direction
|
|
------------------------------------------------------------------------------------------------
|
|
- return: new read direction
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-UCHAR ToggleReadDirection(UCHAR readDirection) {
|
|
- if (readDirection == FROM_LEFT_TO_RIGHT) {
|
|
- return FROM_RIGHT_TO_LEFT;
|
|
- } else {
|
|
- return FROM_LEFT_TO_RIGHT;
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function returns a bit from the bitstream according to
|
|
-read direction. It is called very often, therefore it makes sense to inline it
|
|
-(runtime).
|
|
------------------------------------------------------------------------------------------------
|
|
- input: - handle to FDK bitstream
|
|
- - reference value marking start of bitfield
|
|
- - pLeftStartOfSegment
|
|
- - pRightStartOfSegment
|
|
- - readDirection
|
|
------------------------------------------------------------------------------------------------
|
|
- return: - bit from bitstream
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|
- INT *pLeftStartOfSegment,
|
|
- INT *pRightStartOfSegment, UCHAR readDirection) {
|
|
- UINT bit;
|
|
- INT readBitOffset;
|
|
-
|
|
- if (readDirection == FROM_LEFT_TO_RIGHT) {
|
|
- readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pLeftStartOfSegment;
|
|
- if (readBitOffset) {
|
|
- FDKpushBiDirectional(bs, readBitOffset);
|
|
- }
|
|
-
|
|
- bit = FDKreadBits(bs, 1);
|
|
-
|
|
- *pLeftStartOfSegment += 1;
|
|
- } else {
|
|
- readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pRightStartOfSegment;
|
|
- if (readBitOffset) {
|
|
- FDKpushBiDirectional(bs, readBitOffset);
|
|
- }
|
|
-
|
|
- /* to be replaced with a brother function of FDKreadBits() */
|
|
- bit = FDKreadBits(bs, 1);
|
|
- FDKpushBack(bs, 2);
|
|
-
|
|
- *pRightStartOfSegment -= 1;
|
|
- }
|
|
-
|
|
- return (bit);
|
|
-}
|
|
--- a/libAACdec/src/aacdec_hcr_bit.h
|
|
+++ /dev/null
|
|
@@ -1,114 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s): Robert Weidner (DSP Solutions)
|
|
-
|
|
- Description: HCR Decoder: Bitstream reading prototypes
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-#ifndef AACDEC_HCR_BIT_H
|
|
-#define AACDEC_HCR_BIT_H
|
|
-
|
|
-#include "aacdec_hcr.h"
|
|
-
|
|
-UCHAR ToggleReadDirection(UCHAR readDirection);
|
|
-
|
|
-UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|
- INT *pLeftStartOfSegment,
|
|
- INT *pRightStartOfSegment, UCHAR readDirection);
|
|
-
|
|
-#endif /* AACDEC_HCR_BIT_H */
|
|
--- a/libAACdec/src/aacdec_hcr_types.h
|
|
+++ /dev/null
|
|
@@ -1,432 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s): Robert Weidner (DSP Solutions)
|
|
-
|
|
- Description: HCR Decoder: Common defines and structures; defines for
|
|
- switching error-generator, -detector, and -concealment;
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-#ifndef AACDEC_HCR_TYPES_H
|
|
-#define AACDEC_HCR_TYPES_H
|
|
-
|
|
-#include "FDK_bitstream.h"
|
|
-#include "overlapadd.h"
|
|
-
|
|
-/* ------------------------------------------------ */
|
|
-/* ------------------------------------------------ */
|
|
-
|
|
-#define LINES_PER_UNIT 4
|
|
-
|
|
-/* ------------------------------------------------ */
|
|
-/* ------------------------------------------------ */
|
|
-/* ----------- basic HCR configuration ------------ */
|
|
-
|
|
-#define MAX_SFB_HCR \
|
|
- (((1024 / 8) / LINES_PER_UNIT) * 8) /* (8 * 16) is not enough because sfbs \
|
|
- are split in units for blocktype \
|
|
- short */
|
|
-#define NUMBER_OF_UNIT_GROUPS (LINES_PER_UNIT * 8)
|
|
-#define LINES_PER_UNIT_GROUP (1024 / NUMBER_OF_UNIT_GROUPS) /* 15 16 30 32 */
|
|
-
|
|
-/* ------------------------------------------------ */
|
|
-/* ------------------------------------------------ */
|
|
-/* ------------------------------------------------ */
|
|
-
|
|
-#define FROM_LEFT_TO_RIGHT 0
|
|
-#define FROM_RIGHT_TO_LEFT 1
|
|
-
|
|
-#define MAX_CB_PAIRS 23
|
|
-#define MAX_HCR_SETS 14
|
|
-
|
|
-#define ESCAPE_VALUE 16
|
|
-#define POSITION_OF_FLAG_A 21
|
|
-#define POSITION_OF_FLAG_B 20
|
|
-
|
|
-#define MAX_CB 32 /* last used CB is cb #31 when VCB11 is used */
|
|
-
|
|
-#define MAX_CB_CHECK \
|
|
- 32 /* support for VCB11 available -- is more general, could therefore used \
|
|
- in both cases */
|
|
-
|
|
-#define NUMBER_OF_BIT_IN_WORD 32
|
|
-
|
|
-/* log */
|
|
-#define THIRTYTWO_LOG_DIV_TWO_LOG 5
|
|
-#define EIGHT_LOG_DIV_TWO_LOG 3
|
|
-#define FOUR_LOG_DIV_TWO_LOG 2
|
|
-
|
|
-/* borders */
|
|
-#define CPE_TOP_LENGTH 12288
|
|
-#define SCE_TOP_LENGTH 6144
|
|
-#define LEN_OF_LONGEST_CW_TOP_LENGTH 49
|
|
-
|
|
-/* qsc's of high level */
|
|
-#define Q_VALUE_INVALID \
|
|
- 8192 /* mark a invalid line with this value (to be concealed later on) */
|
|
-#define HCR_DIRAC 500 /* a line of high level */
|
|
-
|
|
-/* masks */
|
|
-#define MASK_LEFT 0xFFF000
|
|
-#define MASK_RIGHT 0xFFF
|
|
-#define CLR_BIT_10 0x3FF
|
|
-#define TEST_BIT_10 0x400
|
|
-
|
|
-#define LEFT_OFFSET 12
|
|
-
|
|
-/* when set HCR is replaced by a dummy-module which just fills the outputbuffer
|
|
- * with a dirac sequence */
|
|
-/* use this if HCR is suspected to write in other modules -- if error is stell
|
|
- * there, HCR is innocent */
|
|
-
|
|
-/* ------------------------------ */
|
|
-/* - insert HCR errors - */
|
|
-/* ------------------------------ */
|
|
-
|
|
-/* modify input lengths -- high protected */
|
|
-#define ERROR_LORSD 0 /* offset: error if different from zero */
|
|
-#define ERROR_LOLC 0 /* offset: error if different from zero */
|
|
-
|
|
-/* segments are earlier empty as expected when decoding PCWs */
|
|
-#define ERROR_PCW_BODY \
|
|
- 0 /* set a positive values to trigger the error (make segments earlyer \
|
|
- appear to be empty) */
|
|
-#define ERROR_PCW_BODY_SIGN \
|
|
- 0 /* set a positive values to trigger the error (make segments earlyer \
|
|
- appear to be empty) */
|
|
-#define ERROR_PCW_BODY_SIGN_ESC \
|
|
- 0 /* set a positive values to trigger the error (make segments earlyer \
|
|
- appear to be empty) */
|
|
-
|
|
-/* pretend there are too many bits decoded (enlarge length of codeword) at PCWs
|
|
- * -- use a positive value */
|
|
-#define ERROR_PCW_BODY_ONLY_TOO_LONG \
|
|
- 0 /* set a positive values to trigger the error */
|
|
-#define ERROR_PCW_BODY_SIGN_TOO_LONG \
|
|
- 0 /* set a positive values to trigger the error */
|
|
-#define ERROR_PCW_BODY_SIGN_ESC_TOO_LONG \
|
|
- 0 /* set a positive values to trigger the error */
|
|
-
|
|
-/* modify HCR bitstream block */
|
|
-
|
|
-#define MODULO_DIVISOR_HCR 30
|
|
-
|
|
-/* ------------------------------ */
|
|
-/* - detect HCR errors - */
|
|
-/* ------------------------------ */
|
|
-/* check input data */
|
|
-
|
|
-/* during decoding */
|
|
-
|
|
-/* all the segments are checked -- therefore -- if this check passes, its a kind
|
|
- of evidence that the decoded PCWs and non-PCWs are fine */
|
|
-
|
|
-/* if a codeword is decoded there exists a border for the number of bits, which
|
|
- are allowed to read for this codeword. This border is the minimum of the
|
|
- length of the longest codeword (for the currently used codebook) and the
|
|
- separately transmitted 'lengthOfLongestCodeword' in this frame and channel.
|
|
- The number of decoded bits is counted (for PCWs only -- there it makes really
|
|
- sense in my opinion). If this number exceeds the border (derived as minimum
|
|
- -- see above), a error is detected. */
|
|
-
|
|
-/* -----------------------------------------------------------------------------------------------------
|
|
- This error check could be set to zero because due to a test within
|
|
- RVLC-Escape-huffman-Decoder a too long codeword could not be detected -- it
|
|
- seems that for RVLC-Escape-Codeword the coderoom is used to 100%. Therefore I
|
|
- assume that the coderoom is used to 100% also for the codebooks 1..11 used at
|
|
- HCR Therefore this test is deactivated pending further notice
|
|
- -----------------------------------------------------------------------------------------------------
|
|
- */
|
|
-
|
|
-/* test if the number of remaining bits in a segment is _below_ zero. If there
|
|
- are no errors the lowest allowed value for remainingBitsInSegment is zero.
|
|
- This check also could be set to zero (save runtime) */
|
|
-
|
|
-/* other */
|
|
-/* when set to '1', avoid setting the LAV-Flag in errorLog due to a
|
|
- previous-line-marking (at PCW decoder). A little more runtime is needed then
|
|
- when writing values out into output-buffer. */
|
|
-
|
|
-/* ------------------------------ */
|
|
-/* - conceal HCR errors - */
|
|
-/* ------------------------------ */
|
|
-
|
|
-#define HCR_ERROR_CONCEALMENT \
|
|
- 1 /* if set to '1', HCR _mutes_ the erred quantized spectral coefficients */
|
|
-
|
|
-// ------------------------------------------------------------------------------------------------------------------
|
|
-// errorLog: A word of 32 bits used for
|
|
-// logging possible errors within HCR
|
|
-// in case of distorted
|
|
-// bitstreams. Table of all
|
|
-// known errors:
|
|
-// ------------------------------------------------------------------------------------------------------------------------
|
|
-// bit fatal location meaning
|
|
-// ----+-----+-----------+--------------------------------------
|
|
-#define SEGMENT_OVERRIDE_ERR_PCW_BODY \
|
|
- 0x80000000 // 31 no PCW-Dec During PCW decoding it is checked after
|
|
- // every PCW if there are too many bits decoded (immediate
|
|
- // check).
|
|
-#define SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN \
|
|
- 0x40000000 // 30 no PCW-Dec During PCW decoding it is checked after
|
|
- // every PCW if there are too many bits decoded (immediate
|
|
- // check).
|
|
-#define SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN_ESC \
|
|
- 0x20000000 // 29 no PCW-Dec During PCW decoding it is checked after
|
|
- // every PCW if there are too many bits decoded (immediate
|
|
- // check).
|
|
-#define EXTENDED_SORTED_COUNTER_OVERFLOW \
|
|
- 0x10000000 // 28 yes Init-Dec Error during extending sideinfo
|
|
- // (neither a PCW nor a nonPCW was decoded so far)
|
|
- // 0x08000000 // 27 reserved
|
|
- // 0x04000000 // 26 reserved
|
|
- // 0x02000000 // 25 reserved
|
|
- // 0x01000000 // 24 reserved
|
|
- // 0x00800000 // 23 reserved
|
|
- // 0x00400000 // 22 reserved
|
|
- // 0x00200000 // 21 reserved
|
|
- // 0x00100000 // 20 reserved
|
|
-
|
|
-/* special errors */
|
|
-#define TOO_MANY_PCW_BODY_BITS_DECODED \
|
|
- 0x00080000 // 19 yes PCW-Dec During PCW-body-decoding too many bits
|
|
- // have been read from bitstream -- advice: skip non-PCW decoding
|
|
-#define TOO_MANY_PCW_BODY_SIGN_BITS_DECODED \
|
|
- 0x00040000 // 18 yes PCW-Dec During PCW-body-sign-decoding too many
|
|
- // bits have been read from bitstream -- advice: skip non-PCW
|
|
- // decoding
|
|
-#define TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED \
|
|
- 0x00020000 // 17 yes PCW-Dec During PCW-body-sign-esc-decoding too
|
|
- // many bits have been read from bitstream -- advice: skip
|
|
- // non-PCW decoding
|
|
-
|
|
-// 0x00010000 // 16 reserved
|
|
-#define STATE_ERROR_BODY_ONLY \
|
|
- 0x00008000 // 15 no NonPCW-Dec State machine returned with error
|
|
-#define STATE_ERROR_BODY_SIGN__BODY \
|
|
- 0x00004000 // 14 no NonPCW-Dec State machine returned with error
|
|
-#define STATE_ERROR_BODY_SIGN__SIGN \
|
|
- 0x00002000 // 13 no NonPCW-Dec State machine returned with error
|
|
-#define STATE_ERROR_BODY_SIGN_ESC__BODY \
|
|
- 0x00001000 // 12 no NonPCW-Dec State machine returned with error
|
|
-#define STATE_ERROR_BODY_SIGN_ESC__SIGN \
|
|
- 0x00000800 // 11 no NonPCW-Dec State machine returned with error
|
|
-#define STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX \
|
|
- 0x00000400 // 10 no NonPCW-Dec State machine returned with error
|
|
-#define STATE_ERROR_BODY_SIGN_ESC__ESC_WORD \
|
|
- 0x00000200 // 9 no NonPCW-Dec State machine returned with error
|
|
-#define HCR_SI_LENGTHS_FAILURE \
|
|
- 0x00000100 // 8 yes Init-Dec LengthOfLongestCodeword must not be
|
|
- // less than lenghtOfReorderedSpectralData
|
|
-#define NUM_SECT_OUT_OF_RANGE_SHORT_BLOCK \
|
|
- 0x00000080 // 7 yes Init-Dec The number of sections is not within
|
|
- // the allowed range (short block)
|
|
-#define NUM_SECT_OUT_OF_RANGE_LONG_BLOCK \
|
|
- 0x00000040 // 6 yes Init-Dec The number of sections is not within
|
|
- // the allowed range (long block)
|
|
-#define LINE_IN_SECT_OUT_OF_RANGE_SHORT_BLOCK \
|
|
- 0x00000020 // 5 yes Init-Dec The number of lines per section is not
|
|
- // within the allowed range (short block)
|
|
-#define CB_OUT_OF_RANGE_SHORT_BLOCK \
|
|
- 0x00000010 // 4 yes Init-Dec The codebook is not within the allowed
|
|
- // range (short block)
|
|
-#define LINE_IN_SECT_OUT_OF_RANGE_LONG_BLOCK \
|
|
- 0x00000008 // 3 yes Init-Dec The number of lines per section is not
|
|
- // within the allowed range (long block)
|
|
-#define CB_OUT_OF_RANGE_LONG_BLOCK \
|
|
- 0x00000004 // 2 yes Init-Dec The codebook is not within the allowed
|
|
- // range (long block)
|
|
-#define LAV_VIOLATION \
|
|
- 0x00000002 // 1 no Final The absolute value of at least one
|
|
- // decoded line was too high for the according codebook.
|
|
-#define BIT_IN_SEGMENTATION_ERROR \
|
|
- 0x00000001 // 0 no Final After PCW and non-PWC-decoding at least
|
|
- // one segment is not zero (global check).
|
|
-
|
|
-/*----------*/
|
|
-#define HCR_FATAL_PCW_ERROR_MASK 0x100E01FC
|
|
-
|
|
-typedef enum { PCW_BODY, PCW_BODY_SIGN, PCW_BODY_SIGN_ESC } PCW_TYPE;
|
|
-
|
|
-/* interface Decoder <---> HCR */
|
|
-typedef struct {
|
|
- UINT errorLog;
|
|
- SPECTRAL_PTR pQuantizedSpectralCoefficientsBase;
|
|
- int quantizedSpectralCoefficientsIdx;
|
|
- SHORT lengthOfReorderedSpectralData;
|
|
- SHORT numSection;
|
|
- SHORT *pNumLineInSect;
|
|
- INT bitstreamAnchor;
|
|
- SCHAR lengthOfLongestCodeword;
|
|
- UCHAR *pCodebook;
|
|
-} HCR_INPUT_OUTPUT;
|
|
-
|
|
-typedef struct {
|
|
- const UCHAR *pMinOfCbPair;
|
|
- const UCHAR *pMaxOfCbPair;
|
|
-} HCR_CB_PAIRS;
|
|
-
|
|
-typedef struct {
|
|
- const USHORT *pLargestAbsVal;
|
|
- const UCHAR *pMaxCwLength;
|
|
- const UCHAR *pCbDimension;
|
|
- const UCHAR *pCbDimShift;
|
|
- const UCHAR *pCbSign;
|
|
- const UCHAR *pCbPriority;
|
|
-} HCR_TABLE_INFO;
|
|
-
|
|
-typedef struct {
|
|
- UINT numSegment;
|
|
- UINT pSegmentBitfield[((1024 >> 1) / NUMBER_OF_BIT_IN_WORD + 1)];
|
|
- UINT pCodewordBitfield[((1024 >> 1) / NUMBER_OF_BIT_IN_WORD + 1)];
|
|
- UINT segmentOffset;
|
|
- INT pLeftStartOfSegment[1024 >> 1];
|
|
- INT pRightStartOfSegment[1024 >> 1];
|
|
- SCHAR pRemainingBitsInSegment[1024 >> 1];
|
|
- UCHAR readDirection;
|
|
- UCHAR numWordForBitfield;
|
|
- USHORT pNumBitValidInLastWord;
|
|
-} HCR_SEGMENT_INFO;
|
|
-
|
|
-typedef struct {
|
|
- UINT numCodeword;
|
|
- UINT numSortedSection;
|
|
- USHORT pNumCodewordInSection[MAX_SFB_HCR];
|
|
- USHORT pNumSortedCodewordInSection[MAX_SFB_HCR];
|
|
- USHORT pNumExtendedSortedCodewordInSection[MAX_SFB_HCR + MAX_HCR_SETS];
|
|
- int numExtendedSortedCodewordInSectionIdx;
|
|
- USHORT pNumExtendedSortedSectionsInSets[MAX_HCR_SETS];
|
|
- int numExtendedSortedSectionsInSetsIdx;
|
|
- USHORT pReorderOffset[MAX_SFB_HCR];
|
|
- UCHAR pSortedCodebook[MAX_SFB_HCR];
|
|
-
|
|
- UCHAR pExtendedSortedCodebook[MAX_SFB_HCR + MAX_HCR_SETS];
|
|
- int extendedSortedCodebookIdx;
|
|
- UCHAR pMaxLenOfCbInExtSrtSec[MAX_SFB_HCR + MAX_HCR_SETS];
|
|
- int maxLenOfCbInExtSrtSecIdx;
|
|
- UCHAR pCodebookSwitch[MAX_SFB_HCR];
|
|
-} HCR_SECTION_INFO;
|
|
-
|
|
-typedef UINT (*STATEFUNC)(HANDLE_FDK_BITSTREAM, void *);
|
|
-
|
|
-typedef struct {
|
|
- /* worst-case and 1024/4 non-PCWs exist in worst-case */
|
|
- FIXP_DBL
|
|
- *pResultBase; /* Base address for spectral data output target buffer */
|
|
- UINT iNode[1024 >> 2]; /* Helper indices for code books */
|
|
- USHORT
|
|
- iResultPointer[1024 >> 2]; /* Helper indices for accessing pResultBase */
|
|
- UINT pEscapeSequenceInfo[1024 >> 2];
|
|
- UINT codewordOffset;
|
|
- STATEFUNC pState;
|
|
- UCHAR pCodebook[1024 >> 2];
|
|
- UCHAR pCntSign[1024 >> 2];
|
|
- /* this array holds the states coded as integer values within the range
|
|
- * [0,1,..,7] */
|
|
- SCHAR pSta[1024 >> 2];
|
|
-} HCR_NON_PCW_SIDEINFO;
|
|
-
|
|
-typedef struct {
|
|
- HCR_INPUT_OUTPUT decInOut;
|
|
- HCR_SEGMENT_INFO segmentInfo;
|
|
- HCR_SECTION_INFO sectionInfo;
|
|
- HCR_NON_PCW_SIDEINFO nonPcwSideinfo;
|
|
-} CErHcrInfo;
|
|
-
|
|
-typedef CErHcrInfo *H_HCR_INFO;
|
|
-
|
|
-#endif /* AACDEC_HCR_TYPES_H */
|
|
--- a/libAACdec/src/aacdec_hcrs.cpp
|
|
+++ /dev/null
|
|
@@ -1,1551 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s): Robert Weidner (DSP Solutions)
|
|
-
|
|
- Description: HCR Decoder: Prepare decoding of non-PCWs, segmentation- and
|
|
- bitfield-handling, HCR-Statemachine
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-#include "aacdec_hcrs.h"
|
|
-
|
|
-#include "aacdec_hcr.h"
|
|
-
|
|
-#include "aacdec_hcr_bit.h"
|
|
-#include "aac_rom.h"
|
|
-#include "aac_ram.h"
|
|
-
|
|
-static UINT InitSegmentBitfield(UINT *pNumSegment,
|
|
- SCHAR *pRemainingBitsInSegment,
|
|
- UINT *pSegmentBitfield,
|
|
- UCHAR *pNumWordForBitfield,
|
|
- USHORT *pNumBitValidInLastWord);
|
|
-
|
|
-static void InitNonPCWSideInformationForCurrentSet(H_HCR_INFO pHcr);
|
|
-
|
|
-static INT ModuloValue(INT input, INT bufferlength);
|
|
-
|
|
-static void ClearBitFromBitfield(STATEFUNC *ptrState, UINT offset,
|
|
- UINT *pBitfield);
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function decodes all non-priority codewords (non-PCWs) by
|
|
-using a state-machine.
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-void DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
|
|
- UINT numValidSegment;
|
|
- INT segmentOffset;
|
|
- INT codewordOffsetBase;
|
|
- INT codewordOffset;
|
|
- UINT trial;
|
|
-
|
|
- UINT *pNumSegment;
|
|
- SCHAR *pRemainingBitsInSegment;
|
|
- UINT *pSegmentBitfield;
|
|
- UCHAR *pNumWordForBitfield;
|
|
- USHORT *pNumBitValidInLastWord;
|
|
- UINT *pCodewordBitfield;
|
|
- INT bitfieldWord;
|
|
- INT bitInWord;
|
|
- UINT tempWord;
|
|
- UINT interMediateWord;
|
|
- INT tempBit;
|
|
- INT carry;
|
|
-
|
|
- UINT numCodeword;
|
|
- UCHAR numSet;
|
|
- UCHAR currentSet;
|
|
- UINT codewordInSet;
|
|
- UINT remainingCodewordsInSet;
|
|
- SCHAR *pSta;
|
|
- UINT ret;
|
|
-
|
|
- pNumSegment = &(pHcr->segmentInfo.numSegment);
|
|
- pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
|
|
- pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
|
|
- pNumWordForBitfield = &(pHcr->segmentInfo.numWordForBitfield);
|
|
- pNumBitValidInLastWord = &(pHcr->segmentInfo.pNumBitValidInLastWord);
|
|
- pSta = pHcr->nonPcwSideinfo.pSta;
|
|
-
|
|
- numValidSegment = InitSegmentBitfield(pNumSegment, pRemainingBitsInSegment,
|
|
- pSegmentBitfield, pNumWordForBitfield,
|
|
- pNumBitValidInLastWord);
|
|
-
|
|
- if (numValidSegment != 0) {
|
|
- numCodeword = pHcr->sectionInfo.numCodeword;
|
|
- numSet = ((numCodeword - 1) / *pNumSegment) + 1;
|
|
-
|
|
- pHcr->segmentInfo.readDirection = FROM_RIGHT_TO_LEFT;
|
|
-
|
|
- /* Process sets subsequently */
|
|
- for (currentSet = 1; currentSet < numSet; currentSet++) {
|
|
- /* step 1 */
|
|
- numCodeword -=
|
|
- *pNumSegment; /* number of remaining non PCWs [for all sets] */
|
|
- if (numCodeword < *pNumSegment) {
|
|
- codewordInSet = numCodeword; /* for last set */
|
|
- } else {
|
|
- codewordInSet = *pNumSegment; /* for all sets except last set */
|
|
- }
|
|
-
|
|
- /* step 2 */
|
|
- /* prepare array 'CodewordBitfield'; as much ones are written from left in
|
|
- * all words, as much decodedCodewordInSetCounter nonPCWs exist in this
|
|
- * set */
|
|
- tempWord = 0xFFFFFFFF;
|
|
- pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
|
|
-
|
|
- for (bitfieldWord = *pNumWordForBitfield; bitfieldWord != 0;
|
|
- bitfieldWord--) { /* loop over all used words */
|
|
- if (codewordInSet > NUMBER_OF_BIT_IN_WORD) { /* more codewords than
|
|
- number of bits => fill
|
|
- ones */
|
|
- /* fill a whole word with ones */
|
|
- *pCodewordBitfield++ = tempWord;
|
|
- codewordInSet -= NUMBER_OF_BIT_IN_WORD; /* subtract number of bits */
|
|
- } else {
|
|
- /* prepare last tempWord */
|
|
- for (remainingCodewordsInSet = codewordInSet;
|
|
- remainingCodewordsInSet < NUMBER_OF_BIT_IN_WORD;
|
|
- remainingCodewordsInSet++) {
|
|
- tempWord =
|
|
- tempWord &
|
|
- ~(1
|
|
- << (NUMBER_OF_BIT_IN_WORD - 1 -
|
|
- remainingCodewordsInSet)); /* set a zero at bit number
|
|
- (NUMBER_OF_BIT_IN_WORD-1-i)
|
|
- in tempWord */
|
|
- }
|
|
- *pCodewordBitfield++ = tempWord;
|
|
- tempWord = 0x00000000;
|
|
- }
|
|
- }
|
|
- pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
|
|
-
|
|
- /* step 3 */
|
|
- /* build non-PCW sideinfo for each non-PCW of the current set */
|
|
- InitNonPCWSideInformationForCurrentSet(pHcr);
|
|
-
|
|
- /* step 4 */
|
|
- /* decode all non-PCWs belonging to this set */
|
|
-
|
|
- /* loop over trials */
|
|
- codewordOffsetBase = 0;
|
|
- for (trial = *pNumSegment; trial > 0; trial--) {
|
|
- /* loop over number of words in bitfields */
|
|
- segmentOffset = 0; /* start at zero in every segment */
|
|
- pHcr->segmentInfo.segmentOffset =
|
|
- segmentOffset; /* store in structure for states */
|
|
- codewordOffset = codewordOffsetBase;
|
|
- pHcr->nonPcwSideinfo.codewordOffset =
|
|
- codewordOffset; /* store in structure for states */
|
|
-
|
|
- for (bitfieldWord = 0; bitfieldWord < *pNumWordForBitfield;
|
|
- bitfieldWord++) {
|
|
- /* derive tempWord with bitwise and */
|
|
- tempWord =
|
|
- pSegmentBitfield[bitfieldWord] & pCodewordBitfield[bitfieldWord];
|
|
-
|
|
- /* if tempWord is not zero, decode something */
|
|
- if (tempWord != 0) {
|
|
- /* loop over all bits in tempWord; start state machine if & is true
|
|
- */
|
|
- for (bitInWord = NUMBER_OF_BIT_IN_WORD; bitInWord > 0;
|
|
- bitInWord--) {
|
|
- interMediateWord = ((UINT)1 << (bitInWord - 1));
|
|
- if ((tempWord & interMediateWord) == interMediateWord) {
|
|
- /* get state and start state machine */
|
|
- pHcr->nonPcwSideinfo.pState =
|
|
- aStateConstant2State[pSta[codewordOffset]];
|
|
-
|
|
- while (pHcr->nonPcwSideinfo.pState) {
|
|
- ret = ((STATEFUNC)pHcr->nonPcwSideinfo.pState)(bs, pHcr);
|
|
- if (ret != 0) {
|
|
- return;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- /* update both offsets */
|
|
- segmentOffset += 1; /* add NUMBER_OF_BIT_IN_WORD times one */
|
|
- pHcr->segmentInfo.segmentOffset = segmentOffset;
|
|
- codewordOffset += 1; /* add NUMBER_OF_BIT_IN_WORD times one */
|
|
- codewordOffset =
|
|
- ModuloValue(codewordOffset,
|
|
- *pNumSegment); /* index of the current codeword
|
|
- lies within modulo range */
|
|
- pHcr->nonPcwSideinfo.codewordOffset = codewordOffset;
|
|
- }
|
|
- } else {
|
|
- segmentOffset +=
|
|
- NUMBER_OF_BIT_IN_WORD; /* add NUMBER_OF_BIT_IN_WORD at once */
|
|
- pHcr->segmentInfo.segmentOffset = segmentOffset;
|
|
- codewordOffset +=
|
|
- NUMBER_OF_BIT_IN_WORD; /* add NUMBER_OF_BIT_IN_WORD at once */
|
|
- codewordOffset = ModuloValue(
|
|
- codewordOffset,
|
|
- *pNumSegment); /* index of the current codeword lies within
|
|
- modulo range */
|
|
- pHcr->nonPcwSideinfo.codewordOffset = codewordOffset;
|
|
- }
|
|
- } /* end of bitfield word loop */
|
|
-
|
|
- /* decrement codeword - pointer */
|
|
- codewordOffsetBase -= 1;
|
|
- codewordOffsetBase =
|
|
- ModuloValue(codewordOffsetBase, *pNumSegment); /* index of the
|
|
- current codeword
|
|
- base lies within
|
|
- modulo range */
|
|
-
|
|
- /* rotate numSegment bits in codewordBitfield */
|
|
- /* rotation of *numSegment bits in bitfield of codewords
|
|
- * (circle-rotation) */
|
|
- /* get last valid bit */
|
|
- tempBit = pCodewordBitfield[*pNumWordForBitfield - 1] &
|
|
- (1 << (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord));
|
|
- tempBit = tempBit >> (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord);
|
|
-
|
|
- /* write zero into place where tempBit was fetched from */
|
|
- pCodewordBitfield[*pNumWordForBitfield - 1] =
|
|
- pCodewordBitfield[*pNumWordForBitfield - 1] &
|
|
- ~(1 << (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord));
|
|
-
|
|
- /* rotate last valid word */
|
|
- pCodewordBitfield[*pNumWordForBitfield - 1] =
|
|
- pCodewordBitfield[*pNumWordForBitfield - 1] >> 1;
|
|
-
|
|
- /* transfare carry bit 0 from current word into bitposition 31 from next
|
|
- * word and rotate current word */
|
|
- for (bitfieldWord = *pNumWordForBitfield - 2; bitfieldWord > -1;
|
|
- bitfieldWord--) {
|
|
- /* get carry (=bit at position 0) from current word */
|
|
- carry = pCodewordBitfield[bitfieldWord] & 1;
|
|
-
|
|
- /* put the carry bit at position 31 into word right from current word
|
|
- */
|
|
- pCodewordBitfield[bitfieldWord + 1] =
|
|
- pCodewordBitfield[bitfieldWord + 1] |
|
|
- (carry << (NUMBER_OF_BIT_IN_WORD - 1));
|
|
-
|
|
- /* shift current word */
|
|
- pCodewordBitfield[bitfieldWord] =
|
|
- pCodewordBitfield[bitfieldWord] >> 1;
|
|
- }
|
|
-
|
|
- /* put tempBit into free bit-position 31 from first word */
|
|
- pCodewordBitfield[0] =
|
|
- pCodewordBitfield[0] | (tempBit << (NUMBER_OF_BIT_IN_WORD - 1));
|
|
-
|
|
- } /* end of trial loop */
|
|
-
|
|
- /* toggle read direction */
|
|
- pHcr->segmentInfo.readDirection =
|
|
- ToggleReadDirection(pHcr->segmentInfo.readDirection);
|
|
- }
|
|
- /* end of set loop */
|
|
-
|
|
- /* all non-PCWs of this spectrum are decoded */
|
|
- }
|
|
-
|
|
- /* all PCWs and all non PCWs are decoded. They are unbacksorted in output
|
|
- * buffer. Here is the Interface with comparing QSCs to asm decoding */
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function prepares the bitfield used for the
|
|
- segments. The list is set up once to be used in all
|
|
-following sets. If a segment is decoded empty, the according bit from the
|
|
-Bitfield is removed.
|
|
------------------------------------------------------------------------------------------------
|
|
- return: numValidSegment = the number of valid segments
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-static UINT InitSegmentBitfield(UINT *pNumSegment,
|
|
- SCHAR *pRemainingBitsInSegment,
|
|
- UINT *pSegmentBitfield,
|
|
- UCHAR *pNumWordForBitfield,
|
|
- USHORT *pNumBitValidInLastWord) {
|
|
- SHORT i;
|
|
- USHORT r;
|
|
- UCHAR bitfieldWord;
|
|
- UINT tempWord;
|
|
- USHORT numValidSegment;
|
|
-
|
|
- *pNumWordForBitfield =
|
|
- (*pNumSegment == 0)
|
|
- ? 0
|
|
- : ((*pNumSegment - 1) >> THIRTYTWO_LOG_DIV_TWO_LOG) + 1;
|
|
-
|
|
- /* loop over all words, which are completely used or only partial */
|
|
- /* bit in pSegmentBitfield is zero if segment is empty; bit in
|
|
- * pSegmentBitfield is one if segment is not empty */
|
|
- numValidSegment = 0;
|
|
- *pNumBitValidInLastWord = *pNumSegment;
|
|
-
|
|
- /* loop over words */
|
|
- for (bitfieldWord = 0; bitfieldWord < *pNumWordForBitfield - 1;
|
|
- bitfieldWord++) {
|
|
- tempWord = 0xFFFFFFFF; /* set ones */
|
|
- r = bitfieldWord << THIRTYTWO_LOG_DIV_TWO_LOG;
|
|
- for (i = 0; i < NUMBER_OF_BIT_IN_WORD; i++) {
|
|
- if (pRemainingBitsInSegment[r + i] == 0) {
|
|
- tempWord = tempWord & ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 -
|
|
- i)); /* set a zero at bit number
|
|
- (NUMBER_OF_BIT_IN_WORD-1-i) in
|
|
- tempWord */
|
|
- } else {
|
|
- numValidSegment += 1; /* count segments which are not empty */
|
|
- }
|
|
- }
|
|
- pSegmentBitfield[bitfieldWord] = tempWord; /* store result */
|
|
- *pNumBitValidInLastWord -= NUMBER_OF_BIT_IN_WORD; /* calculate number of
|
|
- zeros on LSB side in
|
|
- the last word */
|
|
- }
|
|
-
|
|
- /* calculate last word: prepare special tempWord */
|
|
- tempWord = 0xFFFFFFFF;
|
|
- for (i = 0; i < (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord); i++) {
|
|
- tempWord = tempWord & ~(1 << i); /* clear bit i in tempWord */
|
|
- }
|
|
-
|
|
- /* calculate last word */
|
|
- r = bitfieldWord << THIRTYTWO_LOG_DIV_TWO_LOG;
|
|
- for (i = 0; i < *pNumBitValidInLastWord; i++) {
|
|
- if (pRemainingBitsInSegment[r + i] == 0) {
|
|
- tempWord = tempWord & ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 -
|
|
- i)); /* set a zero at bit number
|
|
- (NUMBER_OF_BIT_IN_WORD-1-i) in
|
|
- tempWord */
|
|
- } else {
|
|
- numValidSegment += 1; /* count segments which are not empty */
|
|
- }
|
|
- }
|
|
- pSegmentBitfield[bitfieldWord] = tempWord; /* store result */
|
|
-
|
|
- return numValidSegment;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function sets up sideinfo for the non-PCW decoder (for the
|
|
-current set).
|
|
----------------------------------------------------------------------------------------------*/
|
|
-static void InitNonPCWSideInformationForCurrentSet(H_HCR_INFO pHcr) {
|
|
- USHORT i, k;
|
|
- UCHAR codebookDim;
|
|
- UINT startNode;
|
|
-
|
|
- UCHAR *pCodebook = pHcr->nonPcwSideinfo.pCodebook;
|
|
- UINT *iNode = pHcr->nonPcwSideinfo.iNode;
|
|
- UCHAR *pCntSign = pHcr->nonPcwSideinfo.pCntSign;
|
|
- USHORT *iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
|
|
- UINT *pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
|
|
- SCHAR *pSta = pHcr->nonPcwSideinfo.pSta;
|
|
- USHORT *pNumExtendedSortedCodewordInSection =
|
|
- pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
|
|
- int numExtendedSortedCodewordInSectionIdx =
|
|
- pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
|
|
- UCHAR *pExtendedSortedCodebook = pHcr->sectionInfo.pExtendedSortedCodebook;
|
|
- int extendedSortedCodebookIdx = pHcr->sectionInfo.extendedSortedCodebookIdx;
|
|
- USHORT *pNumExtendedSortedSectionsInSets =
|
|
- pHcr->sectionInfo.pNumExtendedSortedSectionsInSets;
|
|
- int numExtendedSortedSectionsInSetsIdx =
|
|
- pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
|
|
- int quantizedSpectralCoefficientsIdx =
|
|
- pHcr->decInOut.quantizedSpectralCoefficientsIdx;
|
|
- const UCHAR *pCbDimension = aDimCb;
|
|
- int iterationCounter = 0;
|
|
-
|
|
- /* loop over number of extended sorted sections in the current set so all
|
|
- * codewords sideinfo variables within this set can be prepared for decoding
|
|
- */
|
|
- for (i = pNumExtendedSortedSectionsInSets[numExtendedSortedSectionsInSetsIdx];
|
|
- i != 0; i--) {
|
|
- codebookDim =
|
|
- pCbDimension[pExtendedSortedCodebook[extendedSortedCodebookIdx]];
|
|
- startNode = *aHuffTable[pExtendedSortedCodebook[extendedSortedCodebookIdx]];
|
|
-
|
|
- for (k = pNumExtendedSortedCodewordInSection
|
|
- [numExtendedSortedCodewordInSectionIdx];
|
|
- k != 0; k--) {
|
|
- iterationCounter++;
|
|
- if (iterationCounter > (1024 >> 2)) {
|
|
- return;
|
|
- }
|
|
- *pSta++ = aCodebook2StartInt
|
|
- [pExtendedSortedCodebook[extendedSortedCodebookIdx]];
|
|
- *pCodebook++ = pExtendedSortedCodebook[extendedSortedCodebookIdx];
|
|
- *iNode++ = startNode;
|
|
- *pCntSign++ = 0;
|
|
- *iResultPointer++ = quantizedSpectralCoefficientsIdx;
|
|
- *pEscapeSequenceInfo++ = 0;
|
|
- quantizedSpectralCoefficientsIdx +=
|
|
- codebookDim; /* update pointer by codebookDim --> point to next
|
|
- starting value for writing out */
|
|
- if (quantizedSpectralCoefficientsIdx >= 1024) {
|
|
- return;
|
|
- }
|
|
- }
|
|
- numExtendedSortedCodewordInSectionIdx++; /* inc ptr for next ext sort sec in
|
|
- current set */
|
|
- extendedSortedCodebookIdx++; /* inc ptr for next ext sort sec in current set
|
|
- */
|
|
- if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS) ||
|
|
- extendedSortedCodebookIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
|
|
- return;
|
|
- }
|
|
- }
|
|
- numExtendedSortedSectionsInSetsIdx++; /* inc ptr for next set of non-PCWs */
|
|
- if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
|
|
- return;
|
|
- }
|
|
-
|
|
- /* Write back indexes */
|
|
- pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
|
|
- numExtendedSortedCodewordInSectionIdx;
|
|
- pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx;
|
|
- pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx =
|
|
- numExtendedSortedSectionsInSetsIdx;
|
|
- pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
|
|
- numExtendedSortedCodewordInSectionIdx;
|
|
- pHcr->decInOut.quantizedSpectralCoefficientsIdx =
|
|
- quantizedSpectralCoefficientsIdx;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function returns the input value if the value is in the
|
|
- range of bufferlength. If <input> is smaller, one bufferlength
|
|
-is added, if <input> is bigger one bufferlength is subtracted.
|
|
------------------------------------------------------------------------------------------------
|
|
- return: modulo result
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-static INT ModuloValue(INT input, INT bufferlength) {
|
|
- if (input > (bufferlength - 1)) {
|
|
- return (input - bufferlength);
|
|
- }
|
|
- if (input < 0) {
|
|
- return (input + bufferlength);
|
|
- }
|
|
- return input;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This function clears a bit from current bitfield and
|
|
- switches off the statemachine.
|
|
-
|
|
- A bit is cleared in two cases:
|
|
- a) a codeword is decoded, then a bit is cleared in codeword
|
|
-bitfield b) a segment is decoded empty, then a bit is cleared in segment
|
|
-bitfield
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-static void ClearBitFromBitfield(STATEFUNC *ptrState, UINT offset,
|
|
- UINT *pBitfield) {
|
|
- UINT numBitfieldWord;
|
|
- UINT numBitfieldBit;
|
|
-
|
|
- /* get both values needed for clearing the bit */
|
|
- numBitfieldWord = offset >> THIRTYTWO_LOG_DIV_TWO_LOG; /* int = wordNr */
|
|
- numBitfieldBit = offset - (numBitfieldWord
|
|
- << THIRTYTWO_LOG_DIV_TWO_LOG); /* fract = bitNr */
|
|
-
|
|
- /* clear a bit in bitfield */
|
|
- pBitfield[numBitfieldWord] =
|
|
- pBitfield[numBitfieldWord] &
|
|
- ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 - numBitfieldBit));
|
|
-
|
|
- /* switch off state machine because codeword is decoded and/or because segment
|
|
- * is empty */
|
|
- *ptrState = NULL;
|
|
-}
|
|
-
|
|
-/* =========================================================================================
|
|
- the states of the statemachine
|
|
- =========================================================================================
|
|
- */
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Decodes the body of a codeword. This State is used for
|
|
-codebooks 1,2,5 and 6. No sign bits are decoded, because the table of the
|
|
-quantized spectral values has got a valid sign at the quantized spectral lines.
|
|
------------------------------------------------------------------------------------------------
|
|
- output: Two or four quantizes spectral values written at position
|
|
-where pResultPointr points to
|
|
------------------------------------------------------------------------------------------------
|
|
- return: 0
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-UINT Hcr_State_BODY_ONLY(HANDLE_FDK_BITSTREAM bs, void *ptr) {
|
|
- H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
|
|
- UINT *pSegmentBitfield;
|
|
- UINT *pCodewordBitfield;
|
|
- UINT segmentOffset;
|
|
- FIXP_DBL *pResultBase;
|
|
- UINT *iNode;
|
|
- USHORT *iResultPointer;
|
|
- UINT codewordOffset;
|
|
- UINT branchNode;
|
|
- UINT branchValue;
|
|
- UINT iQSC;
|
|
- UINT treeNode;
|
|
- UCHAR carryBit;
|
|
- INT *pLeftStartOfSegment;
|
|
- INT *pRightStartOfSegment;
|
|
- SCHAR *pRemainingBitsInSegment;
|
|
- UCHAR readDirection;
|
|
- UCHAR *pCodebook;
|
|
- UCHAR dimCntr;
|
|
- const UINT *pCurrentTree;
|
|
- const UCHAR *pCbDimension;
|
|
- const SCHAR *pQuantVal;
|
|
- const SCHAR *pQuantValBase;
|
|
-
|
|
- pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
|
|
- pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
|
|
- pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
|
|
- readDirection = pHcr->segmentInfo.readDirection;
|
|
- pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
|
|
- pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
|
|
- segmentOffset = pHcr->segmentInfo.segmentOffset;
|
|
-
|
|
- pCodebook = pHcr->nonPcwSideinfo.pCodebook;
|
|
- iNode = pHcr->nonPcwSideinfo.iNode;
|
|
- pResultBase = pHcr->nonPcwSideinfo.pResultBase;
|
|
- iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
|
|
- codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
|
|
-
|
|
- pCbDimension = aDimCb;
|
|
-
|
|
- treeNode = iNode[codewordOffset];
|
|
- pCurrentTree = aHuffTable[pCodebook[codewordOffset]];
|
|
-
|
|
- for (; pRemainingBitsInSegment[segmentOffset] > 0;
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1) {
|
|
- carryBit = HcrGetABitFromBitstream(
|
|
- bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
|
|
- &pRightStartOfSegment[segmentOffset], readDirection);
|
|
-
|
|
- CarryBitToBranchValue(carryBit, /* make a step in decoding tree */
|
|
- treeNode, &branchValue, &branchNode);
|
|
-
|
|
- /* if end of branch reached write out lines and count bits needed for sign,
|
|
- * otherwise store node in codeword sideinfo */
|
|
- if ((branchNode & TEST_BIT_10) ==
|
|
- TEST_BIT_10) { /* test bit 10 ; ==> body is complete */
|
|
- pQuantValBase = aQuantTable[pCodebook[codewordOffset]]; /* get base
|
|
- address of
|
|
- quantized
|
|
- values
|
|
- belonging to
|
|
- current
|
|
- codebook */
|
|
- pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid
|
|
- line [of 2 or 4 quantized
|
|
- values] */
|
|
-
|
|
- iQSC = iResultPointer[codewordOffset]; /* get position of first line for
|
|
- writing out result */
|
|
-
|
|
- for (dimCntr = pCbDimension[pCodebook[codewordOffset]]; dimCntr != 0;
|
|
- dimCntr--) {
|
|
- pResultBase[iQSC++] =
|
|
- (FIXP_DBL)*pQuantVal++; /* write out 2 or 4 lines into
|
|
- spectrum; no Sign bits
|
|
- available in this state */
|
|
- }
|
|
-
|
|
- ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pCodewordBitfield); /* clear a bit in bitfield and
|
|
- switch off statemachine */
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
|
|
- for loop counter (see
|
|
- above) is done here */
|
|
- break; /* end of branch in tree reached i.e. a whole nonPCW-Body is
|
|
- decoded */
|
|
- } else { /* body is not decoded completely: */
|
|
- treeNode = *(
|
|
- pCurrentTree +
|
|
- branchValue); /* update treeNode for further step in decoding tree */
|
|
- }
|
|
- }
|
|
- iNode[codewordOffset] = treeNode; /* store updated treeNode because maybe
|
|
- decoding of codeword body not finished
|
|
- yet */
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] <= 0) {
|
|
- ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pSegmentBitfield); /* clear a bit in bitfield and
|
|
- switch off statemachine */
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] < 0) {
|
|
- pHcr->decInOut.errorLog |= STATE_ERROR_BODY_ONLY;
|
|
- return BODY_ONLY;
|
|
- }
|
|
- }
|
|
-
|
|
- return STOP_THIS_STATE;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Decodes the codeword body, writes out result and counts the
|
|
-number of quantized spectral values, which are different form zero. For those
|
|
-values sign bits are needed.
|
|
-
|
|
- If sign bit counter cntSign is different from zero, switch to
|
|
-next state to decode sign Bits there. If sign bit counter cntSign is zero, no
|
|
-sign bits are needed and codeword is decoded.
|
|
------------------------------------------------------------------------------------------------
|
|
- output: Two or four written quantizes spectral values written at
|
|
-position where pResultPointr points to. The signs of those lines may be wrong.
|
|
-If the signs [on just one signle sign] is wrong, the next state will correct it.
|
|
------------------------------------------------------------------------------------------------
|
|
- return: 0
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-UINT Hcr_State_BODY_SIGN__BODY(HANDLE_FDK_BITSTREAM bs, void *ptr) {
|
|
- H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
|
|
- SCHAR *pRemainingBitsInSegment;
|
|
- INT *pLeftStartOfSegment;
|
|
- INT *pRightStartOfSegment;
|
|
- UCHAR readDirection;
|
|
- UINT *pSegmentBitfield;
|
|
- UINT *pCodewordBitfield;
|
|
- UINT segmentOffset;
|
|
-
|
|
- UCHAR *pCodebook;
|
|
- UINT *iNode;
|
|
- UCHAR *pCntSign;
|
|
- FIXP_DBL *pResultBase;
|
|
- USHORT *iResultPointer;
|
|
- UINT codewordOffset;
|
|
-
|
|
- UINT iQSC;
|
|
- UINT cntSign;
|
|
- UCHAR dimCntr;
|
|
- UCHAR carryBit;
|
|
- SCHAR *pSta;
|
|
- UINT treeNode;
|
|
- UINT branchValue;
|
|
- UINT branchNode;
|
|
- const UCHAR *pCbDimension;
|
|
- const UINT *pCurrentTree;
|
|
- const SCHAR *pQuantValBase;
|
|
- const SCHAR *pQuantVal;
|
|
-
|
|
- pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
|
|
- pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
|
|
- pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
|
|
- readDirection = pHcr->segmentInfo.readDirection;
|
|
- pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
|
|
- pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
|
|
- segmentOffset = pHcr->segmentInfo.segmentOffset;
|
|
-
|
|
- pCodebook = pHcr->nonPcwSideinfo.pCodebook;
|
|
- iNode = pHcr->nonPcwSideinfo.iNode;
|
|
- pCntSign = pHcr->nonPcwSideinfo.pCntSign;
|
|
- pResultBase = pHcr->nonPcwSideinfo.pResultBase;
|
|
- iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
|
|
- codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
|
|
- pSta = pHcr->nonPcwSideinfo.pSta;
|
|
-
|
|
- pCbDimension = aDimCb;
|
|
-
|
|
- treeNode = iNode[codewordOffset];
|
|
- pCurrentTree = aHuffTable[pCodebook[codewordOffset]];
|
|
-
|
|
- for (; pRemainingBitsInSegment[segmentOffset] > 0;
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1) {
|
|
- carryBit = HcrGetABitFromBitstream(
|
|
- bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
|
|
- &pRightStartOfSegment[segmentOffset], readDirection);
|
|
-
|
|
- CarryBitToBranchValue(carryBit, /* make a step in decoding tree */
|
|
- treeNode, &branchValue, &branchNode);
|
|
-
|
|
- /* if end of branch reached write out lines and count bits needed for sign,
|
|
- * otherwise store node in codeword sideinfo */
|
|
- if ((branchNode & TEST_BIT_10) ==
|
|
- TEST_BIT_10) { /* test bit 10 ; if set body complete */
|
|
- /* body completely decoded; branchValue is valid, set pQuantVal to first
|
|
- * (of two or four) quantized spectral coefficients */
|
|
- pQuantValBase = aQuantTable[pCodebook[codewordOffset]]; /* get base
|
|
- address of
|
|
- quantized
|
|
- values
|
|
- belonging to
|
|
- current
|
|
- codebook */
|
|
- pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid
|
|
- line [of 2 or 4 quantized
|
|
- values] */
|
|
-
|
|
- iQSC = iResultPointer[codewordOffset]; /* get position of first line for
|
|
- writing result */
|
|
-
|
|
- /* codeword decoding result is written out here: Write out 2 or 4
|
|
- * quantized spectral values with probably */
|
|
- /* wrong sign and count number of values which are different from zero for
|
|
- * sign bit decoding [which happens in next state] */
|
|
- cntSign = 0;
|
|
- for (dimCntr = pCbDimension[pCodebook[codewordOffset]]; dimCntr != 0;
|
|
- dimCntr--) {
|
|
- pResultBase[iQSC++] =
|
|
- (FIXP_DBL)*pQuantVal; /* write quant. spec. coef. into spectrum */
|
|
- if (*pQuantVal++ != 0) {
|
|
- cntSign += 1;
|
|
- }
|
|
- }
|
|
-
|
|
- if (cntSign == 0) {
|
|
- ClearBitFromBitfield(
|
|
- &(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pCodewordBitfield); /* clear a bit in bitfield and switch off
|
|
- statemachine */
|
|
- } else {
|
|
- pCntSign[codewordOffset] = cntSign; /* write sign count result into
|
|
- codewordsideinfo of current
|
|
- codeword */
|
|
- pSta[codewordOffset] = BODY_SIGN__SIGN; /* change state */
|
|
- pHcr->nonPcwSideinfo.pState =
|
|
- aStateConstant2State[pSta[codewordOffset]]; /* get state from
|
|
- separate array of
|
|
- cw-sideinfo */
|
|
- }
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
|
|
- for loop counter (see
|
|
- above) is done here */
|
|
- break; /* end of branch in tree reached i.e. a whole nonPCW-Body is
|
|
- decoded */
|
|
- } else { /* body is not decoded completely: */
|
|
- treeNode = *(
|
|
- pCurrentTree +
|
|
- branchValue); /* update treeNode for further step in decoding tree */
|
|
- }
|
|
- }
|
|
- iNode[codewordOffset] = treeNode; /* store updated treeNode because maybe
|
|
- decoding of codeword body not finished
|
|
- yet */
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] <= 0) {
|
|
- ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pSegmentBitfield); /* clear a bit in bitfield and
|
|
- switch off statemachine */
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] < 0) {
|
|
- pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN__BODY;
|
|
- return BODY_SIGN__BODY;
|
|
- }
|
|
- }
|
|
-
|
|
- return STOP_THIS_STATE;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This state decodes the sign bits belonging to a codeword. The
|
|
-state is called as often in different "trials" until pCntSgn[codewordOffset] is
|
|
-zero.
|
|
------------------------------------------------------------------------------------------------
|
|
- output: The two or four quantizes spectral values (written in previous
|
|
-state) have now the correct sign.
|
|
------------------------------------------------------------------------------------------------
|
|
- return: 0
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) {
|
|
- H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
|
|
- SCHAR *pRemainingBitsInSegment;
|
|
- INT *pLeftStartOfSegment;
|
|
- INT *pRightStartOfSegment;
|
|
- UCHAR readDirection;
|
|
- UINT *pSegmentBitfield;
|
|
- UINT *pCodewordBitfield;
|
|
- UINT segmentOffset;
|
|
-
|
|
- UCHAR *pCntSign;
|
|
- FIXP_DBL *pResultBase;
|
|
- USHORT *iResultPointer;
|
|
- UINT codewordOffset;
|
|
-
|
|
- UCHAR carryBit;
|
|
- UINT iQSC;
|
|
- UCHAR cntSign;
|
|
-
|
|
- pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
|
|
- pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
|
|
- pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
|
|
- readDirection = pHcr->segmentInfo.readDirection;
|
|
- pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
|
|
- pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
|
|
- segmentOffset = pHcr->segmentInfo.segmentOffset;
|
|
-
|
|
- /*pCodebook = */
|
|
- pCntSign = pHcr->nonPcwSideinfo.pCntSign;
|
|
- pResultBase = pHcr->nonPcwSideinfo.pResultBase;
|
|
- iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
|
|
- codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
|
|
-
|
|
- iQSC = iResultPointer[codewordOffset];
|
|
- cntSign = pCntSign[codewordOffset];
|
|
-
|
|
- /* loop for sign bit decoding */
|
|
- for (; pRemainingBitsInSegment[segmentOffset] > 0;
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1) {
|
|
- carryBit = HcrGetABitFromBitstream(
|
|
- bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
|
|
- &pRightStartOfSegment[segmentOffset], readDirection);
|
|
- cntSign -=
|
|
- 1; /* decrement sign counter because one sign bit has been read */
|
|
-
|
|
- /* search for a line (which was decoded in previous state) which is not
|
|
- * zero. [This value will get a sign] */
|
|
- while (pResultBase[iQSC] == (FIXP_DBL)0) {
|
|
- if (++iQSC >= 1024) { /* points to current value different from zero */
|
|
- return BODY_SIGN__SIGN;
|
|
- }
|
|
- }
|
|
-
|
|
- /* put sign together with line; if carryBit is zero, the sign is ok already;
|
|
- * no write operation necessary in this case */
|
|
- if (carryBit != 0) {
|
|
- pResultBase[iQSC] = -pResultBase[iQSC]; /* carryBit = 1 --> minus */
|
|
- }
|
|
-
|
|
- iQSC++; /* update pointer to next (maybe valid) value */
|
|
-
|
|
- if (cntSign == 0) { /* if (cntSign==0) ==> set state CODEWORD_DECODED */
|
|
- ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pCodewordBitfield); /* clear a bit in bitfield and
|
|
- switch off statemachine */
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
|
|
- for loop counter (see
|
|
- above) is done here */
|
|
- break; /* whole nonPCW-Body and according sign bits are decoded */
|
|
- }
|
|
- }
|
|
- pCntSign[codewordOffset] = cntSign;
|
|
- iResultPointer[codewordOffset] = iQSC; /* store updated pResultPointer */
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] <= 0) {
|
|
- ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pSegmentBitfield); /* clear a bit in bitfield and
|
|
- switch off statemachine */
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] < 0) {
|
|
- pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN__SIGN;
|
|
- return BODY_SIGN__SIGN;
|
|
- }
|
|
- }
|
|
-
|
|
- return STOP_THIS_STATE;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Decodes the codeword body in case of codebook is 11. Writes
|
|
-out resulting two or four lines [with probably wrong sign] and counts the number
|
|
-of lines, which are different form zero. This information is needed in next
|
|
- state where sign bits will be decoded, if necessary.
|
|
- If sign bit counter cntSign is zero, no sign bits are needed
|
|
-and codeword is decoded completely.
|
|
------------------------------------------------------------------------------------------------
|
|
- output: Two lines (quantizes spectral coefficients) which are probably
|
|
-wrong. The sign may be wrong and if one or two values is/are 16, the following
|
|
-states will decode the escape sequence to correct the values which are wirtten
|
|
-here.
|
|
------------------------------------------------------------------------------------------------
|
|
- return: 0
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-UINT Hcr_State_BODY_SIGN_ESC__BODY(HANDLE_FDK_BITSTREAM bs, void *ptr) {
|
|
- H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
|
|
- SCHAR *pRemainingBitsInSegment;
|
|
- INT *pLeftStartOfSegment;
|
|
- INT *pRightStartOfSegment;
|
|
- UCHAR readDirection;
|
|
- UINT *pSegmentBitfield;
|
|
- UINT *pCodewordBitfield;
|
|
- UINT segmentOffset;
|
|
-
|
|
- UINT *iNode;
|
|
- UCHAR *pCntSign;
|
|
- FIXP_DBL *pResultBase;
|
|
- USHORT *iResultPointer;
|
|
- UINT codewordOffset;
|
|
-
|
|
- UCHAR carryBit;
|
|
- UINT iQSC;
|
|
- UINT cntSign;
|
|
- UINT dimCntr;
|
|
- UINT treeNode;
|
|
- SCHAR *pSta;
|
|
- UINT branchNode;
|
|
- UINT branchValue;
|
|
- const UINT *pCurrentTree;
|
|
- const SCHAR *pQuantValBase;
|
|
- const SCHAR *pQuantVal;
|
|
-
|
|
- pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
|
|
- pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
|
|
- pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
|
|
- readDirection = pHcr->segmentInfo.readDirection;
|
|
- pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
|
|
- pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
|
|
- segmentOffset = pHcr->segmentInfo.segmentOffset;
|
|
-
|
|
- iNode = pHcr->nonPcwSideinfo.iNode;
|
|
- pCntSign = pHcr->nonPcwSideinfo.pCntSign;
|
|
- pResultBase = pHcr->nonPcwSideinfo.pResultBase;
|
|
- iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
|
|
- codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
|
|
- pSta = pHcr->nonPcwSideinfo.pSta;
|
|
-
|
|
- treeNode = iNode[codewordOffset];
|
|
- pCurrentTree = aHuffTable[ESCAPE_CODEBOOK];
|
|
-
|
|
- for (; pRemainingBitsInSegment[segmentOffset] > 0;
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1) {
|
|
- carryBit = HcrGetABitFromBitstream(
|
|
- bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
|
|
- &pRightStartOfSegment[segmentOffset], readDirection);
|
|
-
|
|
- /* make a step in tree */
|
|
- CarryBitToBranchValue(carryBit, treeNode, &branchValue, &branchNode);
|
|
-
|
|
- /* if end of branch reached write out lines and count bits needed for sign,
|
|
- * otherwise store node in codeword sideinfo */
|
|
- if ((branchNode & TEST_BIT_10) ==
|
|
- TEST_BIT_10) { /* test bit 10 ; if set body complete */
|
|
-
|
|
- /* body completely decoded; branchValue is valid */
|
|
- /* set pQuantVol to first (of two or four) quantized spectral coefficients
|
|
- */
|
|
- pQuantValBase = aQuantTable[ESCAPE_CODEBOOK]; /* get base address of
|
|
- quantized values
|
|
- belonging to current
|
|
- codebook */
|
|
- pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid
|
|
- line [of 2 or 4 quantized
|
|
- values] */
|
|
-
|
|
- /* make backup from original resultPointer in node storage for state
|
|
- * BODY_SIGN_ESC__SIGN */
|
|
- iNode[codewordOffset] = iResultPointer[codewordOffset];
|
|
-
|
|
- /* get position of first line for writing result */
|
|
- iQSC = iResultPointer[codewordOffset];
|
|
-
|
|
- /* codeword decoding result is written out here: Write out 2 or 4
|
|
- * quantized spectral values with probably */
|
|
- /* wrong sign and count number of values which are different from zero for
|
|
- * sign bit decoding [which happens in next state] */
|
|
- cntSign = 0;
|
|
-
|
|
- for (dimCntr = DIMENSION_OF_ESCAPE_CODEBOOK; dimCntr != 0; dimCntr--) {
|
|
- pResultBase[iQSC++] =
|
|
- (FIXP_DBL)*pQuantVal; /* write quant. spec. coef. into spectrum */
|
|
- if (*pQuantVal++ != 0) {
|
|
- cntSign += 1;
|
|
- }
|
|
- }
|
|
-
|
|
- if (cntSign == 0) {
|
|
- ClearBitFromBitfield(
|
|
- &(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pCodewordBitfield); /* clear a bit in bitfield and switch off
|
|
- statemachine */
|
|
- /* codeword decoded */
|
|
- } else {
|
|
- /* write sign count result into codewordsideinfo of current codeword */
|
|
- pCntSign[codewordOffset] = cntSign;
|
|
- pSta[codewordOffset] = BODY_SIGN_ESC__SIGN; /* change state */
|
|
- pHcr->nonPcwSideinfo.pState =
|
|
- aStateConstant2State[pSta[codewordOffset]]; /* get state from
|
|
- separate array of
|
|
- cw-sideinfo */
|
|
- }
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1; /* the last reinitialzation
|
|
- of for loop counter (see
|
|
- above) is done here */
|
|
- break; /* end of branch in tree reached i.e. a whole nonPCW-Body is
|
|
- decoded */
|
|
- } else { /* body is not decoded completely: */
|
|
- /* update treeNode for further step in decoding tree and store updated
|
|
- * treeNode because maybe no more bits left in segment */
|
|
- treeNode = *(pCurrentTree + branchValue);
|
|
- iNode[codewordOffset] = treeNode;
|
|
- }
|
|
- }
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] <= 0) {
|
|
- ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pSegmentBitfield); /* clear a bit in bitfield and
|
|
- switch off statemachine */
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] < 0) {
|
|
- pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__BODY;
|
|
- return BODY_SIGN_ESC__BODY;
|
|
- }
|
|
- }
|
|
-
|
|
- return STOP_THIS_STATE;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: This state decodes the sign bits, if a codeword of codebook 11
|
|
-needs some. A flag named 'flagB' in codeword sideinfo is set, if the second line
|
|
-of quantized spectral values is 16. The 'flagB' is used in case of decoding of a
|
|
-escape sequence is necessary as far as the second line is concerned.
|
|
-
|
|
- If only the first line needs an escape sequence, the flagB is
|
|
-cleared. If only the second line needs an escape sequence, the flagB is not
|
|
-used.
|
|
-
|
|
- For storing sideinfo in case of escape sequence decoding one
|
|
-single word can be used for both escape sequences because they are decoded not
|
|
-at the same time:
|
|
-
|
|
-
|
|
- bit 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5
|
|
-4 3 2 1 0
|
|
- ===== == == =========== ===========
|
|
-=================================== ^ ^ ^ ^ ^
|
|
-^ | | | | | | res. flagA flagB
|
|
-escapePrefixUp escapePrefixDown escapeWord
|
|
-
|
|
------------------------------------------------------------------------------------------------
|
|
- output: Two lines with correct sign. If one or two values is/are 16,
|
|
-the lines are not valid, otherwise they are.
|
|
------------------------------------------------------------------------------------------------
|
|
- return: 0
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-UINT Hcr_State_BODY_SIGN_ESC__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) {
|
|
- H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
|
|
- SCHAR *pRemainingBitsInSegment;
|
|
- INT *pLeftStartOfSegment;
|
|
- INT *pRightStartOfSegment;
|
|
- UCHAR readDirection;
|
|
- UINT *pSegmentBitfield;
|
|
- UINT *pCodewordBitfield;
|
|
- UINT segmentOffset;
|
|
-
|
|
- UINT *iNode;
|
|
- UCHAR *pCntSign;
|
|
- FIXP_DBL *pResultBase;
|
|
- USHORT *iResultPointer;
|
|
- UINT *pEscapeSequenceInfo;
|
|
- UINT codewordOffset;
|
|
-
|
|
- UINT iQSC;
|
|
- UCHAR cntSign;
|
|
- UINT flagA;
|
|
- UINT flagB;
|
|
- UINT flags;
|
|
- UCHAR carryBit;
|
|
- SCHAR *pSta;
|
|
-
|
|
- pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
|
|
- pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
|
|
- pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
|
|
- readDirection = pHcr->segmentInfo.readDirection;
|
|
- pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
|
|
- pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
|
|
- segmentOffset = pHcr->segmentInfo.segmentOffset;
|
|
-
|
|
- iNode = pHcr->nonPcwSideinfo.iNode;
|
|
- pCntSign = pHcr->nonPcwSideinfo.pCntSign;
|
|
- pResultBase = pHcr->nonPcwSideinfo.pResultBase;
|
|
- iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
|
|
- pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
|
|
- codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
|
|
- pSta = pHcr->nonPcwSideinfo.pSta;
|
|
-
|
|
- iQSC = iResultPointer[codewordOffset];
|
|
- cntSign = pCntSign[codewordOffset];
|
|
-
|
|
- /* loop for sign bit decoding */
|
|
- for (; pRemainingBitsInSegment[segmentOffset] > 0;
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1) {
|
|
- carryBit = HcrGetABitFromBitstream(
|
|
- bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
|
|
- &pRightStartOfSegment[segmentOffset], readDirection);
|
|
-
|
|
- /* decrement sign counter because one sign bit has been read */
|
|
- cntSign -= 1;
|
|
- pCntSign[codewordOffset] = cntSign;
|
|
-
|
|
- /* get a quantized spectral value (which was decoded in previous state)
|
|
- * which is not zero. [This value will get a sign] */
|
|
- while (pResultBase[iQSC] == (FIXP_DBL)0) {
|
|
- if (++iQSC >= 1024) {
|
|
- return BODY_SIGN_ESC__SIGN;
|
|
- }
|
|
- }
|
|
- iResultPointer[codewordOffset] = iQSC;
|
|
-
|
|
- /* put negative sign together with quantized spectral value; if carryBit is
|
|
- * zero, the sign is ok already; no write operation necessary in this case
|
|
- */
|
|
- if (carryBit != 0) {
|
|
- pResultBase[iQSC] = -pResultBase[iQSC]; /* carryBit = 1 --> minus */
|
|
- }
|
|
- iQSC++; /* update index to next (maybe valid) value */
|
|
- iResultPointer[codewordOffset] = iQSC;
|
|
-
|
|
- if (cntSign == 0) {
|
|
- /* all sign bits are decoded now */
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
|
|
- for loop counter (see
|
|
- above) is done here */
|
|
-
|
|
- /* check decoded values if codeword is decoded: Check if one or two escape
|
|
- * sequences 16 follow */
|
|
-
|
|
- /* step 0 */
|
|
- /* restore pointer to first decoded quantized value [ = original
|
|
- * pResultPointr] from index iNode prepared in State_BODY_SIGN_ESC__BODY
|
|
- */
|
|
- iQSC = iNode[codewordOffset];
|
|
-
|
|
- /* step 1 */
|
|
- /* test first value if escape sequence follows */
|
|
- flagA = 0; /* for first possible escape sequence */
|
|
- if (fixp_abs(pResultBase[iQSC++]) == (FIXP_DBL)ESCAPE_VALUE) {
|
|
- flagA = 1;
|
|
- }
|
|
-
|
|
- /* step 2 */
|
|
- /* test second value if escape sequence follows */
|
|
- flagB = 0; /* for second possible escape sequence */
|
|
- if (fixp_abs(pResultBase[iQSC]) == (FIXP_DBL)ESCAPE_VALUE) {
|
|
- flagB = 1;
|
|
- }
|
|
-
|
|
- /* step 3 */
|
|
- /* evaluate flag result and go on if necessary */
|
|
- if (!flagA && !flagB) {
|
|
- ClearBitFromBitfield(
|
|
- &(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pCodewordBitfield); /* clear a bit in bitfield and switch off
|
|
- statemachine */
|
|
- } else {
|
|
- /* at least one of two lines is 16 */
|
|
- /* store both flags at correct positions in non PCW codeword sideinfo
|
|
- * pEscapeSequenceInfo[codewordOffset] */
|
|
- flags = flagA << POSITION_OF_FLAG_A;
|
|
- flags |= (flagB << POSITION_OF_FLAG_B);
|
|
- pEscapeSequenceInfo[codewordOffset] = flags;
|
|
-
|
|
- /* set next state */
|
|
- pSta[codewordOffset] = BODY_SIGN_ESC__ESC_PREFIX;
|
|
- pHcr->nonPcwSideinfo.pState =
|
|
- aStateConstant2State[pSta[codewordOffset]]; /* get state from
|
|
- separate array of
|
|
- cw-sideinfo */
|
|
-
|
|
- /* set result pointer to the first line of the two decoded lines */
|
|
- iResultPointer[codewordOffset] = iNode[codewordOffset];
|
|
-
|
|
- if (!flagA && flagB) {
|
|
- /* update pResultPointr ==> state Stat_BODY_SIGN_ESC__ESC_WORD writes
|
|
- * to correct position. Second value is the one and only escape value
|
|
- */
|
|
- iQSC = iResultPointer[codewordOffset];
|
|
- iQSC++;
|
|
- iResultPointer[codewordOffset] = iQSC;
|
|
- }
|
|
-
|
|
- } /* at least one of two lines is 16 */
|
|
- break; /* nonPCW-Body at cb 11 and according sign bits are decoded */
|
|
-
|
|
- } /* if ( cntSign == 0 ) */
|
|
- } /* loop over remaining Bits in segment */
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] <= 0) {
|
|
- ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pSegmentBitfield); /* clear a bit in bitfield and
|
|
- switch off statemachine */
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] < 0) {
|
|
- pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__SIGN;
|
|
- return BODY_SIGN_ESC__SIGN;
|
|
- }
|
|
- }
|
|
- return STOP_THIS_STATE;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Decode escape prefix of first or second escape sequence. The
|
|
-escape prefix consists of ones. The following zero is also decoded here.
|
|
------------------------------------------------------------------------------------------------
|
|
- output: If the single separator-zero which follows the
|
|
-escape-prefix-ones is not yet decoded: The value 'escapePrefixUp' in word
|
|
-pEscapeSequenceInfo[codewordOffset] is updated.
|
|
-
|
|
- If the single separator-zero which follows the
|
|
-escape-prefix-ones is decoded: Two updated values 'escapePrefixUp' and
|
|
-'escapePrefixDown' in word pEscapeSequenceInfo[codewordOffset]. This State is
|
|
-finished. Switch to next state.
|
|
------------------------------------------------------------------------------------------------
|
|
- return: 0
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM bs, void *ptr) {
|
|
- H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
|
|
- SCHAR *pRemainingBitsInSegment;
|
|
- INT *pLeftStartOfSegment;
|
|
- INT *pRightStartOfSegment;
|
|
- UCHAR readDirection;
|
|
- UINT *pSegmentBitfield;
|
|
- UINT segmentOffset;
|
|
- UINT *pEscapeSequenceInfo;
|
|
- UINT codewordOffset;
|
|
- UCHAR carryBit;
|
|
- UINT escapePrefixUp;
|
|
- SCHAR *pSta;
|
|
-
|
|
- pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
|
|
- pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
|
|
- pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
|
|
- readDirection = pHcr->segmentInfo.readDirection;
|
|
- pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
|
|
- segmentOffset = pHcr->segmentInfo.segmentOffset;
|
|
- pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
|
|
- codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
|
|
- pSta = pHcr->nonPcwSideinfo.pSta;
|
|
-
|
|
- escapePrefixUp =
|
|
- (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_UP) >>
|
|
- LSB_ESCAPE_PREFIX_UP;
|
|
-
|
|
- /* decode escape prefix */
|
|
- for (; pRemainingBitsInSegment[segmentOffset] > 0;
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1) {
|
|
- carryBit = HcrGetABitFromBitstream(
|
|
- bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
|
|
- &pRightStartOfSegment[segmentOffset], readDirection);
|
|
-
|
|
- /* count ones and store sum in escapePrefixUp */
|
|
- if (carryBit == 1) {
|
|
- escapePrefixUp += 1; /* update conter for ones */
|
|
-
|
|
- /* store updated counter in sideinfo of current codeword */
|
|
- pEscapeSequenceInfo[codewordOffset] &=
|
|
- ~MASK_ESCAPE_PREFIX_UP; /* delete old escapePrefixUp */
|
|
- escapePrefixUp <<= LSB_ESCAPE_PREFIX_UP; /* shift to correct position */
|
|
- pEscapeSequenceInfo[codewordOffset] |=
|
|
- escapePrefixUp; /* insert new escapePrefixUp */
|
|
- escapePrefixUp >>= LSB_ESCAPE_PREFIX_UP; /* shift back down */
|
|
- } else { /* separator [zero] reached */
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
|
|
- for loop counter (see
|
|
- above) is done here */
|
|
- escapePrefixUp +=
|
|
- 4; /* if escape_separator '0' appears, add 4 and ==> break */
|
|
-
|
|
- /* store escapePrefixUp in pEscapeSequenceInfo[codewordOffset] at bit
|
|
- * position escapePrefixUp */
|
|
- pEscapeSequenceInfo[codewordOffset] &=
|
|
- ~MASK_ESCAPE_PREFIX_UP; /* delete old escapePrefixUp */
|
|
- escapePrefixUp <<= LSB_ESCAPE_PREFIX_UP; /* shift to correct position */
|
|
- pEscapeSequenceInfo[codewordOffset] |=
|
|
- escapePrefixUp; /* insert new escapePrefixUp */
|
|
- escapePrefixUp >>= LSB_ESCAPE_PREFIX_UP; /* shift back down */
|
|
-
|
|
- /* store escapePrefixUp in pEscapeSequenceInfo[codewordOffset] at bit
|
|
- * position escapePrefixDown */
|
|
- pEscapeSequenceInfo[codewordOffset] &=
|
|
- ~MASK_ESCAPE_PREFIX_DOWN; /* delete old escapePrefixDown */
|
|
- escapePrefixUp <<= LSB_ESCAPE_PREFIX_DOWN; /* shift to correct position */
|
|
- pEscapeSequenceInfo[codewordOffset] |=
|
|
- escapePrefixUp; /* insert new escapePrefixDown */
|
|
-
|
|
- pSta[codewordOffset] = BODY_SIGN_ESC__ESC_WORD; /* set next state */
|
|
- pHcr->nonPcwSideinfo.pState =
|
|
- aStateConstant2State[pSta[codewordOffset]]; /* get state from separate
|
|
- array of cw-sideinfo */
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] <= 0) {
|
|
- ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pSegmentBitfield); /* clear a bit in bitfield and
|
|
- switch off statemachine */
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] < 0) {
|
|
- pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX;
|
|
- return BODY_SIGN_ESC__ESC_PREFIX;
|
|
- }
|
|
- }
|
|
-
|
|
- return STOP_THIS_STATE;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Decode escapeWord of escape sequence. If the escape sequence
|
|
-is decoded completely, assemble quantized-spectral-escape-coefficient and
|
|
-replace the previous decoded 16 by the new value. Test flagB. If flagB is set,
|
|
-the second escape sequence must be decoded. If flagB is not set, the codeword is
|
|
-decoded and the state machine is switched off.
|
|
------------------------------------------------------------------------------------------------
|
|
- output: Two lines with valid sign. At least one of both lines has got
|
|
-the correct value.
|
|
------------------------------------------------------------------------------------------------
|
|
- return: 0
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-UINT Hcr_State_BODY_SIGN_ESC__ESC_WORD(HANDLE_FDK_BITSTREAM bs, void *ptr) {
|
|
- H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
|
|
- SCHAR *pRemainingBitsInSegment;
|
|
- INT *pLeftStartOfSegment;
|
|
- INT *pRightStartOfSegment;
|
|
- UCHAR readDirection;
|
|
- UINT *pSegmentBitfield;
|
|
- UINT *pCodewordBitfield;
|
|
- UINT segmentOffset;
|
|
-
|
|
- FIXP_DBL *pResultBase;
|
|
- USHORT *iResultPointer;
|
|
- UINT *pEscapeSequenceInfo;
|
|
- UINT codewordOffset;
|
|
-
|
|
- UINT escapeWord;
|
|
- UINT escapePrefixDown;
|
|
- UINT escapePrefixUp;
|
|
- UCHAR carryBit;
|
|
- UINT iQSC;
|
|
- INT sign;
|
|
- UINT flagA;
|
|
- UINT flagB;
|
|
- SCHAR *pSta;
|
|
-
|
|
- pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
|
|
- pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
|
|
- pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
|
|
- readDirection = pHcr->segmentInfo.readDirection;
|
|
- pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
|
|
- pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
|
|
- segmentOffset = pHcr->segmentInfo.segmentOffset;
|
|
-
|
|
- pResultBase = pHcr->nonPcwSideinfo.pResultBase;
|
|
- iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
|
|
- pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
|
|
- codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
|
|
- pSta = pHcr->nonPcwSideinfo.pSta;
|
|
-
|
|
- escapeWord = pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_WORD;
|
|
- escapePrefixDown =
|
|
- (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_DOWN) >>
|
|
- LSB_ESCAPE_PREFIX_DOWN;
|
|
-
|
|
- /* decode escape word */
|
|
- for (; pRemainingBitsInSegment[segmentOffset] > 0;
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1) {
|
|
- carryBit = HcrGetABitFromBitstream(
|
|
- bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
|
|
- &pRightStartOfSegment[segmentOffset], readDirection);
|
|
-
|
|
- /* build escape word */
|
|
- escapeWord <<=
|
|
- 1; /* left shift previous decoded part of escapeWord by on bit */
|
|
- escapeWord = escapeWord | carryBit; /* assemble escape word by bitwise or */
|
|
-
|
|
- /* decrement counter for length of escape word because one more bit was
|
|
- * decoded */
|
|
- escapePrefixDown -= 1;
|
|
-
|
|
- /* store updated escapePrefixDown */
|
|
- pEscapeSequenceInfo[codewordOffset] &=
|
|
- ~MASK_ESCAPE_PREFIX_DOWN; /* delete old escapePrefixDown */
|
|
- escapePrefixDown <<= LSB_ESCAPE_PREFIX_DOWN; /* shift to correct position */
|
|
- pEscapeSequenceInfo[codewordOffset] |=
|
|
- escapePrefixDown; /* insert new escapePrefixDown */
|
|
- escapePrefixDown >>= LSB_ESCAPE_PREFIX_DOWN; /* shift back */
|
|
-
|
|
- /* store updated escapeWord */
|
|
- pEscapeSequenceInfo[codewordOffset] &=
|
|
- ~MASK_ESCAPE_WORD; /* delete old escapeWord */
|
|
- pEscapeSequenceInfo[codewordOffset] |=
|
|
- escapeWord; /* insert new escapeWord */
|
|
-
|
|
- if (escapePrefixDown == 0) {
|
|
- pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
|
|
- for loop counter (see
|
|
- above) is done here */
|
|
-
|
|
- /* escape sequence decoded. Assemble escape-line and replace original line
|
|
- */
|
|
-
|
|
- /* step 0 */
|
|
- /* derive sign */
|
|
- iQSC = iResultPointer[codewordOffset];
|
|
- sign = (pResultBase[iQSC] >= (FIXP_DBL)0)
|
|
- ? 1
|
|
- : -1; /* get sign of escape value 16 */
|
|
-
|
|
- /* step 1 */
|
|
- /* get escapePrefixUp */
|
|
- escapePrefixUp =
|
|
- (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_UP) >>
|
|
- LSB_ESCAPE_PREFIX_UP;
|
|
-
|
|
- /* step 2 */
|
|
- /* calculate escape value */
|
|
- pResultBase[iQSC] =
|
|
- (FIXP_DBL)(sign * (((INT)1 << escapePrefixUp) + (INT)escapeWord));
|
|
-
|
|
- /* get both flags from sideinfo (flags are not shifted to the
|
|
- * lsb-position) */
|
|
- flagA = pEscapeSequenceInfo[codewordOffset] & MASK_FLAG_A;
|
|
- flagB = pEscapeSequenceInfo[codewordOffset] & MASK_FLAG_B;
|
|
-
|
|
- /* step 3 */
|
|
- /* clear the whole escape sideinfo word */
|
|
- pEscapeSequenceInfo[codewordOffset] = 0;
|
|
-
|
|
- /* change state in dependence of flag flagB */
|
|
- if (flagA != 0) {
|
|
- /* first escape sequence decoded; previous decoded 16 has been replaced
|
|
- * by valid line */
|
|
-
|
|
- /* clear flagA in sideinfo word because this escape sequence has already
|
|
- * beed decoded */
|
|
- pEscapeSequenceInfo[codewordOffset] &= ~MASK_FLAG_A;
|
|
-
|
|
- if (flagB == 0) {
|
|
- ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pCodewordBitfield); /* clear a bit in bitfield
|
|
- and switch off
|
|
- statemachine */
|
|
- } else {
|
|
- /* updated pointer to next and last 16 */
|
|
- iQSC++;
|
|
- iResultPointer[codewordOffset] = iQSC;
|
|
-
|
|
- /* change state */
|
|
- pSta[codewordOffset] = BODY_SIGN_ESC__ESC_PREFIX;
|
|
- pHcr->nonPcwSideinfo.pState =
|
|
- aStateConstant2State[pSta[codewordOffset]]; /* get state from
|
|
- separate array of
|
|
- cw-sideinfo */
|
|
- }
|
|
- } else {
|
|
- ClearBitFromBitfield(
|
|
- &(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pCodewordBitfield); /* clear a bit in bitfield and switch off
|
|
- statemachine */
|
|
- }
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] <= 0) {
|
|
- ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
|
|
- pSegmentBitfield); /* clear a bit in bitfield and
|
|
- switch off statemachine */
|
|
-
|
|
- if (pRemainingBitsInSegment[segmentOffset] < 0) {
|
|
- pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_WORD;
|
|
- return BODY_SIGN_ESC__ESC_WORD;
|
|
- }
|
|
- }
|
|
-
|
|
- return STOP_THIS_STATE;
|
|
-}
|
|
--- a/libAACdec/src/aacdec_hcrs.h
|
|
+++ /dev/null
|
|
@@ -1,176 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s): Robert Weidner (DSP Solutions)
|
|
-
|
|
- Description: HCR Decoder: Defines of state-constants, masks and
|
|
- state-prototypes
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-#ifndef AACDEC_HCRS_H
|
|
-#define AACDEC_HCRS_H
|
|
-
|
|
-#include "FDK_bitstream.h"
|
|
-#include "aacdec_hcr_types.h"
|
|
-/* The four different kinds of types of states are: */
|
|
-/* different states are defined as constants */ /* start middle=self next
|
|
- stop */
|
|
-#define STOP_THIS_STATE \
|
|
- 0 /* */
|
|
-#define BODY_ONLY \
|
|
- 1 /* X X X */
|
|
-#define BODY_SIGN__BODY \
|
|
- 2 /* X X X X [stop if no sign] */
|
|
-#define BODY_SIGN__SIGN \
|
|
- 3 /* X X [stop if sign bits decoded] */
|
|
-#define BODY_SIGN_ESC__BODY \
|
|
- 4 /* X X X X [stop if no sign] */
|
|
-#define BODY_SIGN_ESC__SIGN \
|
|
- 5 /* X X X [stop if no escape sequence] */
|
|
-#define BODY_SIGN_ESC__ESC_PREFIX \
|
|
- 6 /* X X */
|
|
-#define BODY_SIGN_ESC__ESC_WORD \
|
|
- 7 /* X X X [stop if abs(second qsc) != 16] */
|
|
-
|
|
-/* examples: */
|
|
-
|
|
-/* BODY_ONLY means only the codeword body will be decoded; no
|
|
- * sign bits will follow and no escapesequence will follow */
|
|
-
|
|
-/* BODY_SIGN__BODY means that the codeword consists of two parts;
|
|
- * body and sign part. The part '__BODY' after the two underscores shows */
|
|
-/* that the bits which are currently decoded belong
|
|
- * to the '__BODY' of the codeword and not to the sign part. */
|
|
-
|
|
-/* BODY_SIGN_ESC__ESC_PB means that the codeword consists of three parts;
|
|
- * body, sign and (here: two) escape sequences; */
|
|
-/* P = Prefix = ones */
|
|
-/* W = Escape Word */
|
|
-/* A = first possible (of two) Escape sequeces */
|
|
-/* B = second possible (of two) Escape sequeces */
|
|
-/* The part after the two underscores shows that
|
|
- * the current bits which are decoded belong to the '__ESC_PB' - part of the */
|
|
-/* codeword. That means the body and the sign bits
|
|
- * are decoded completely and the bits which are decoded now belong to */
|
|
-/* the escape sequence [P = prefix; B=second
|
|
- * possible escape sequence] */
|
|
-
|
|
-#define MSB_31_MASK 0x80000000 /* masks MSB (= Bit 31) in a 32 bit word */
|
|
-#define DIMENSION_OF_ESCAPE_CODEBOOK 2 /* for cb >= 11 is dimension 2 */
|
|
-#define ESCAPE_CODEBOOK 11
|
|
-
|
|
-#define MASK_ESCAPE_PREFIX_UP 0x000F0000
|
|
-#define LSB_ESCAPE_PREFIX_UP 16
|
|
-
|
|
-#define MASK_ESCAPE_PREFIX_DOWN 0x0000F000
|
|
-#define LSB_ESCAPE_PREFIX_DOWN 12
|
|
-
|
|
-#define MASK_ESCAPE_WORD 0x00000FFF
|
|
-#define MASK_FLAG_A 0x00200000
|
|
-#define MASK_FLAG_B 0x00100000
|
|
-
|
|
-extern void DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO hHcr);
|
|
-
|
|
-UINT Hcr_State_BODY_ONLY(HANDLE_FDK_BITSTREAM, void*);
|
|
-UINT Hcr_State_BODY_SIGN__BODY(HANDLE_FDK_BITSTREAM, void*);
|
|
-UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM, void*);
|
|
-UINT Hcr_State_BODY_SIGN_ESC__BODY(HANDLE_FDK_BITSTREAM, void*);
|
|
-UINT Hcr_State_BODY_SIGN_ESC__SIGN(HANDLE_FDK_BITSTREAM, void*);
|
|
-UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM, void*);
|
|
-UINT Hcr_State_BODY_SIGN_ESC__ESC_WORD(HANDLE_FDK_BITSTREAM, void*);
|
|
-
|
|
-#endif /* AACDEC_HCRS_H */
|
|
--- a/libAACdec/src/aacdecoder.cpp
|
|
+++ b/libAACdec/src/aacdecoder.cpp
|
|
@@ -163,17 +163,12 @@ amm-info@iis.fraunhofer.de
|
|
|
|
#include "sac_dec_lib.h"
|
|
|
|
-#include "aacdec_hcr.h"
|
|
-#include "rvlc.h"
|
|
-
|
|
#include "usacdec_lpd.h"
|
|
|
|
#include "ac_arith_coder.h"
|
|
|
|
#include "tpdec_lib.h"
|
|
|
|
-#include "conceal.h"
|
|
-
|
|
#include "FDK_crc.h"
|
|
#define PS_IS_EXPLICITLY_DISABLED(aot, flags) \
|
|
(((aot) == AOT_DRM_AAC) && !(flags & AC_PS_PRESENT))
|
|
@@ -1191,10 +1186,6 @@ LINKSPEC_CPP HANDLE_AACDECODER CAacDecod
|
|
/* initialize progam config */
|
|
CProgramConfig_Init(&self->pce);
|
|
|
|
- /* initialize error concealment common data */
|
|
- CConcealment_InitCommonData(&self->concealCommonData);
|
|
- self->concealMethodUser = ConcealMethodNone; /* undefined -> auto mode */
|
|
-
|
|
self->hDrcInfo = GetDrcInfo();
|
|
if (self->hDrcInfo == NULL) {
|
|
goto bail;
|
|
@@ -1202,8 +1193,7 @@ LINKSPEC_CPP HANDLE_AACDECODER CAacDecod
|
|
/* Init common DRC structure */
|
|
aacDecoder_drcInit(self->hDrcInfo);
|
|
/* Set default frame delay */
|
|
- aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY,
|
|
- CConcealment_GetDelay(&self->concealCommonData));
|
|
+ aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY, 0);
|
|
|
|
self->workBufferCore2 = GetWorkBufferCore2();
|
|
if (self->workBufferCore2 == NULL) goto bail;
|
|
@@ -2085,15 +2075,6 @@ CAacDecoder_Init(HANDLE_AACDECODER self,
|
|
if (self->pAacDecoderStaticChannelInfo[ch]->pCpeStaticData !=
|
|
NULL) {
|
|
self->pAacDecoderStaticChannelInfo[ch]
|
|
- ->pCpeStaticData->jointStereoPersistentData
|
|
- .spectralCoeffs[ch2] =
|
|
- self->pAacDecoderStaticChannelInfo[ch]
|
|
- ->concealmentInfo.spectralCoefficient;
|
|
- self->pAacDecoderStaticChannelInfo[ch]
|
|
- ->pCpeStaticData->jointStereoPersistentData.specScale[ch2] =
|
|
- self->pAacDecoderStaticChannelInfo[ch]
|
|
- ->concealmentInfo.specScale;
|
|
- self->pAacDecoderStaticChannelInfo[ch]
|
|
->pCpeStaticData->jointStereoPersistentData.scratchBuffer =
|
|
(FIXP_DBL *)self->pTimeData2;
|
|
}
|
|
@@ -2193,12 +2174,6 @@ CAacDecoder_Init(HANDLE_AACDECODER self,
|
|
/* Delete mixdown metadata from the past */
|
|
pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
|
|
|
|
- /* Reset concealment only if ASC changed. Otherwise it will be done with
|
|
- any config callback. E.g. every time the LATM SMC is present. */
|
|
- CConcealment_InitChannelData(
|
|
- &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
|
|
- &self->concealCommonData, initRenderMode,
|
|
- self->streamInfo.aacSamplesPerFrame);
|
|
ch++;
|
|
chIdx++;
|
|
}
|
|
@@ -2336,12 +2311,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod
|
|
int ch;
|
|
/* Clear history */
|
|
for (ch = 0; ch < self->aacChannels; ch++) {
|
|
- /* Reset concealment */
|
|
- CConcealment_InitChannelData(
|
|
- &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
|
|
- &self->concealCommonData,
|
|
- self->pAacDecoderChannelInfo[0]->renderMode,
|
|
- self->streamInfo.aacSamplesPerFrame);
|
|
/* Clear overlap-add buffers to avoid clicks. */
|
|
FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer,
|
|
OverlapBufferSize * sizeof(FIXP_DBL));
|
|
@@ -2403,15 +2372,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod
|
|
if (ch >= self->aacChannels) {
|
|
return AAC_DEC_UNKNOWN;
|
|
}
|
|
-
|
|
- /* if last frame was broken and this frame is no independent frame,
|
|
- * correct decoding is impossible we need to trigger concealment */
|
|
- if ((CConcealment_GetLastFrameOk(
|
|
- &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
|
|
- 1) == 0) &&
|
|
- !(self->flags[streamIndex] & AC_INDEP)) {
|
|
- self->frameOK = 0;
|
|
- }
|
|
ch++;
|
|
}
|
|
}
|
|
@@ -3081,13 +3041,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod
|
|
* following concealment method, mark the frame as erroneous */
|
|
{
|
|
CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
|
|
- CConcealmentInfo *hConcealmentInfo =
|
|
- &pAacDecoderStaticChannelInfo->concealmentInfo;
|
|
const int mute_release_active =
|
|
- (self->frameOK && !(flags & AACDEC_CONCEAL)) &&
|
|
- ((hConcealmentInfo->concealState >= ConcealState_Mute) &&
|
|
- (hConcealmentInfo->cntValidFrames + 1 <=
|
|
- hConcealmentInfo->pConcealParams->numMuteReleaseFrames));
|
|
+ (self->frameOK && !(flags & AACDEC_CONCEAL));
|
|
const int icsIsInvalid = (GetScaleFactorBandsTransmitted(pIcsInfo) >
|
|
GetScaleFactorBandsTotal(pIcsInfo));
|
|
const int icsInfoUsedinFadeOut =
|
|
@@ -3098,29 +3053,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod
|
|
}
|
|
}
|
|
|
|
- /*
|
|
- Conceal defective spectral data
|
|
- */
|
|
- {
|
|
- CAacDecoderChannelInfo **ppAacDecoderChannelInfo =
|
|
- &pAacDecoderChannelInfo;
|
|
- CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo =
|
|
- &pAacDecoderStaticChannelInfo;
|
|
- {
|
|
- concealApplyReturnCode = CConcealment_Apply(
|
|
- &(*ppAacDecoderStaticChannelInfo)->concealmentInfo,
|
|
- *ppAacDecoderChannelInfo, *ppAacDecoderStaticChannelInfo,
|
|
- &self->samplingRateInfo[streamIndex],
|
|
- self->streamInfo.aacSamplesPerFrame,
|
|
- pAacDecoderStaticChannelInfo->last_lpd_mode,
|
|
- (self->frameOK && !(flags & AACDEC_CONCEAL)),
|
|
- self->flags[streamIndex]);
|
|
- }
|
|
- }
|
|
- if (concealApplyReturnCode == -1) {
|
|
- frameOk_butConceal = 1;
|
|
- }
|
|
-
|
|
if (flags & (AACDEC_INTR)) {
|
|
/* Reset DRC control data for this channel */
|
|
aacDecoder_drcInitChannelData(&pAacDecoderStaticChannelInfo->drcData);
|
|
@@ -3191,20 +3123,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod
|
|
ErrorStatus = AAC_DEC_UNKNOWN;
|
|
break;
|
|
}
|
|
- /* TimeDomainFading */
|
|
- if (!CConceal_TDFading_Applied[c]) {
|
|
- CConceal_TDFading_Applied[c] = CConcealment_TDFading(
|
|
- self->streamInfo.aacSamplesPerFrame,
|
|
- &self->pAacDecoderStaticChannelInfo[c], pTimeData + offset, 0);
|
|
- if (c + 1 < (8) && c < aacChannels - 1) {
|
|
- /* update next TDNoise Seed to avoid muting in case of Parametric
|
|
- * Stereo */
|
|
- self->pAacDecoderStaticChannelInfo[c + 1]
|
|
- ->concealmentInfo.TDNoiseSeed =
|
|
- self->pAacDecoderStaticChannelInfo[c]
|
|
- ->concealmentInfo.TDNoiseSeed;
|
|
- }
|
|
- }
|
|
}
|
|
}
|
|
|
|
@@ -3249,11 +3167,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod
|
|
}
|
|
}
|
|
|
|
- /* Add additional concealment delay */
|
|
- self->streamInfo.outputDelay +=
|
|
- CConcealment_GetDelay(&self->concealCommonData) *
|
|
- self->streamInfo.aacSamplesPerFrame;
|
|
-
|
|
/* Map DRC data to StreamInfo structure */
|
|
aacDecoder_drcGetInfo(self->hDrcInfo, &self->streamInfo.drcPresMode,
|
|
&self->streamInfo.drcProgRefLev);
|
|
--- a/libAACdec/src/aacdecoder.h
|
|
+++ b/libAACdec/src/aacdecoder.h
|
|
@@ -236,9 +236,6 @@ struct AAC_DECODER_INSTANCE {
|
|
1)]; /*!< Pointer to persistent data shared by both channels of a CPE.
|
|
This structure is allocated once for each CPE. */
|
|
|
|
- CConcealParams concealCommonData;
|
|
- CConcealmentMethod concealMethodUser;
|
|
-
|
|
CUsacCoreExtensions usacCoreExt; /*!< Data and handles to extend USAC FD/LPD
|
|
core decoder (SBR, MPS, ...) */
|
|
UINT numUsacElements[(1 * 1)];
|
|
--- a/libAACdec/src/aacdecoder_lib.cpp
|
|
+++ b/libAACdec/src/aacdecoder_lib.cpp
|
|
@@ -107,8 +107,6 @@ amm-info@iis.fraunhofer.de
|
|
#include "tpdec_lib.h"
|
|
#include "FDK_core.h" /* FDK_tools version info */
|
|
|
|
-#include "conceal.h"
|
|
-
|
|
#include "aacdec_drc.h"
|
|
|
|
#include "sac_dec_lib.h"
|
|
@@ -280,26 +278,6 @@ static INT aacDecoder_ConfigCallback(voi
|
|
{ err = aacDecoder_Config(self, pAscStruct, configMode, configChanged); }
|
|
}
|
|
if (err == AAC_DEC_OK) {
|
|
- /*
|
|
- revert concealment method if either
|
|
- - Interpolation concealment might not be meaningful
|
|
- - Interpolation concealment is not implemented
|
|
- */
|
|
- if ((self->flags[0] & (AC_LD | AC_ELD) &&
|
|
- (self->concealMethodUser == ConcealMethodNone) &&
|
|
- CConcealment_GetDelay(&self->concealCommonData) >
|
|
- 0) /* might not be meaningful but allow if user has set it
|
|
- expicitly */
|
|
- || (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) &&
|
|
- CConcealment_GetDelay(&self->concealCommonData) >
|
|
- 0) /* not implemented */
|
|
- ) {
|
|
- /* Revert to error concealment method Noise Substitution.
|
|
- Because interpolation is not implemented for USAC or
|
|
- the additional delay is unwanted for low delay codecs. */
|
|
- setConcealMethod(self, 1);
|
|
- }
|
|
- aacDecoder_setMetadataExpiry(self, self->metadataExpiry);
|
|
errTp = TRANSPORTDEC_OK;
|
|
} else {
|
|
if (err == AAC_DEC_NEED_TO_RESTART) {
|
|
@@ -529,17 +507,12 @@ static AAC_DECODER_ERROR setConcealMetho
|
|
const HANDLE_AACDECODER self, /*!< Handle of the decoder instance */
|
|
const INT method) {
|
|
AAC_DECODER_ERROR errorStatus = AAC_DEC_OK;
|
|
- CConcealParams *pConcealData = NULL;
|
|
int method_revert = 0;
|
|
HANDLE_AAC_DRC hDrcInfo = NULL;
|
|
HANDLE_PCM_DOWNMIX hPcmDmx = NULL;
|
|
- CConcealmentMethod backupMethod = ConcealMethodNone;
|
|
- int backupDelay = 0;
|
|
- int bsDelay = 0;
|
|
|
|
/* check decoder handle */
|
|
if (self != NULL) {
|
|
- pConcealData = &self->concealCommonData;
|
|
hDrcInfo = self->hDrcInfo;
|
|
hPcmDmx = self->hPcmUtils;
|
|
if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && method >= 2) {
|
|
@@ -555,33 +528,13 @@ static AAC_DECODER_ERROR setConcealMetho
|
|
}
|
|
}
|
|
|
|
- /* Get current method/delay */
|
|
- backupMethod = CConcealment_GetMethod(pConcealData);
|
|
- backupDelay = CConcealment_GetDelay(pConcealData);
|
|
-
|
|
- /* Be sure to set AAC and SBR concealment method simultaneously! */
|
|
- errorStatus = CConcealment_SetParams(
|
|
- pConcealData,
|
|
- (method_revert == 0) ? (int)method : (int)1, // concealMethod
|
|
- AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealFadeOutSlope
|
|
- AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealFadeInSlope
|
|
- AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealMuteRelease
|
|
- AACDEC_CONCEAL_PARAM_NOT_SPECIFIED // concealComfNoiseLevel
|
|
- );
|
|
- if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
|
|
- goto bail;
|
|
- }
|
|
-
|
|
- /* Get new delay */
|
|
- bsDelay = CConcealment_GetDelay(pConcealData);
|
|
-
|
|
- errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, bsDelay);
|
|
+ errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, 0);
|
|
if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
|
|
goto bail;
|
|
}
|
|
|
|
if (errorStatus == AAC_DEC_OK) {
|
|
- PCMDMX_ERROR err = pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, bsDelay);
|
|
+ PCMDMX_ERROR err = pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, 0);
|
|
switch (err) {
|
|
case PCMDMX_INVALID_HANDLE:
|
|
errorStatus = AAC_DEC_INVALID_HANDLE;
|
|
@@ -596,15 +549,10 @@ static AAC_DECODER_ERROR setConcealMetho
|
|
|
|
bail:
|
|
if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
|
|
- /* Revert to the initial state */
|
|
- CConcealment_SetParams(
|
|
- pConcealData, (int)backupMethod, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,
|
|
- AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,
|
|
- AACDEC_CONCEAL_PARAM_NOT_SPECIFIED);
|
|
/* Revert DRC bitstream delay */
|
|
- aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, backupDelay);
|
|
+ aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, 0);
|
|
/* Revert PCM mixdown bitstream delay */
|
|
- pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, backupDelay);
|
|
+ pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, 0);
|
|
}
|
|
|
|
return errorStatus;
|
|
@@ -834,9 +782,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecode
|
|
packed into a helper function which keeps all modules and libs in a
|
|
consistent state even in the case an error occures. */
|
|
errorStatus = setConcealMethod(self, value);
|
|
- if (errorStatus == AAC_DEC_OK) {
|
|
- self->concealMethodUser = (CConcealmentMethod)value;
|
|
- }
|
|
break;
|
|
|
|
default:
|
|
@@ -966,8 +911,7 @@ LINKSPEC_CPP HANDLE_AACDECODER aacDecode
|
|
aacDec->limiterEnableCurr = 0;
|
|
|
|
/* Assure that all modules have same delay */
|
|
- if (setConcealMethod(aacDec,
|
|
- CConcealment_GetMethod(&aacDec->concealCommonData))) {
|
|
+ if (setConcealMethod(aacDec, 0)) {
|
|
err = -1;
|
|
goto bail;
|
|
}
|
|
@@ -1359,9 +1303,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER
|
|
break;
|
|
}
|
|
|
|
- if ((ErrorStatus != AAC_DEC_OK) || (flags & AACDEC_CONCEAL) ||
|
|
- self->pAacDecoderStaticChannelInfo[0]->concealmentInfo.concealState >
|
|
- ConcealState_FadeIn) {
|
|
+ if ((ErrorStatus != AAC_DEC_OK) || (flags & AACDEC_CONCEAL)) {
|
|
self->frameOK = 0; /* if an error has occured do concealment in the SBR
|
|
decoder too */
|
|
}
|
|
@@ -1457,9 +1399,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER
|
|
domain signal before the QMF synthesis. Therefore the DRC gains
|
|
need to be delayed by the QMF synthesis delay. */
|
|
if (self->mpsEnableCurr) drcDelay = 257;
|
|
- /* Take into account concealment delay */
|
|
- drcDelay += CConcealment_GetDelay(&self->concealCommonData) *
|
|
- self->streamInfo.frameSize;
|
|
|
|
for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
|
|
UCHAR mapValue = FDK_chMapDescr_getMapValue(
|
|
--- a/libAACdec/src/block.cpp
|
|
+++ b/libAACdec/src/block.cpp
|
|
@@ -114,9 +114,6 @@ amm-info@iis.fraunhofer.de
|
|
|
|
#include "ac_arith_coder.h"
|
|
|
|
-#include "aacdec_hcr.h"
|
|
-#include "rvlc.h"
|
|
-
|
|
#if defined(__arm__)
|
|
#include "arm/block_arm.cpp"
|
|
#endif
|
|
@@ -331,12 +328,7 @@ AAC_DECODER_ERROR CBlock_ReadSectionData
|
|
int group;
|
|
UCHAR sect_cb;
|
|
UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
|
|
- /* HCR input (long) */
|
|
- SHORT *pNumLinesInSec =
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr;
|
|
int numLinesInSecIdx = 0;
|
|
- UCHAR *pHcrCodeBook =
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr;
|
|
const SHORT *BandOffsets = GetScaleFactorBandOffsets(
|
|
&pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
|
|
pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection = 0;
|
|
@@ -376,22 +368,8 @@ AAC_DECODER_ERROR CBlock_ReadSectionData
|
|
top = band + sect_len;
|
|
|
|
if (flags & AC_ER_HCR) {
|
|
- /* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */
|
|
- if (numLinesInSecIdx >= MAX_SFB_HCR) {
|
|
- return AAC_DEC_PARSE_ERROR;
|
|
- }
|
|
- if (top > (int)GetNumberOfScaleFactorBands(
|
|
- &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo)) {
|
|
- return AAC_DEC_PARSE_ERROR;
|
|
- }
|
|
- pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
|
|
- numLinesInSecIdx++;
|
|
- if (sect_cb == BOOKSCL) {
|
|
- return AAC_DEC_INVALID_CODE_BOOK;
|
|
- } else {
|
|
- *pHcrCodeBook++ = sect_cb;
|
|
- }
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection++;
|
|
+ /* HCR disabled */
|
|
+ return AAC_DEC_PARSE_ERROR;
|
|
}
|
|
|
|
/* Check spectral line limits */
|
|
@@ -718,41 +696,12 @@ AAC_DECODER_ERROR CBlock_ReadSpectralDat
|
|
/* plain huffman decoding (short) finished */
|
|
}
|
|
|
|
- /* HCR - Huffman Codeword Reordering short */
|
|
else /* if ( flags & AC_ER_HCR ) */
|
|
|
|
{
|
|
- H_HCR_INFO hHcr = &pAacDecoderChannelInfo->pComData->overlay.aac.erHcrInfo;
|
|
-
|
|
- int hcrStatus = 0;
|
|
-
|
|
- /* advanced Huffman decoding starts here (HCR decoding :) */
|
|
- if (pAacDecoderChannelInfo->pDynData->specificTo.aac
|
|
- .lenOfReorderedSpectralData != 0) {
|
|
- /* HCR initialization short */
|
|
- hcrStatus = HcrInit(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
|
|
-
|
|
- if (hcrStatus != 0) {
|
|
- return AAC_DEC_DECODE_FRAME_ERROR;
|
|
- }
|
|
-
|
|
- /* HCR decoding short */
|
|
- hcrStatus =
|
|
- HcrDecoder(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
|
|
-
|
|
- if (hcrStatus != 0) {
|
|
-#if HCR_ERROR_CONCEALMENT
|
|
- HcrMuteErroneousLines(hHcr);
|
|
-#else
|
|
- return AAC_DEC_DECODE_FRAME_ERROR;
|
|
-#endif /* HCR_ERROR_CONCEALMENT */
|
|
- }
|
|
-
|
|
- FDKpushFor(bs, pAacDecoderChannelInfo->pDynData->specificTo.aac
|
|
- .lenOfReorderedSpectralData);
|
|
- }
|
|
+ /* HCR - Huffman Codeword Reordering disabled */
|
|
+ return AAC_DEC_DECODE_FRAME_ERROR;
|
|
}
|
|
- /* HCR - Huffman Codeword Reordering short finished */
|
|
|
|
if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) &&
|
|
!(flags & (AC_ELD | AC_SCALABLE))) {
|
|
--- a/libAACdec/src/channel.cpp
|
|
+++ b/libAACdec/src/channel.cpp
|
|
@@ -106,12 +106,6 @@ amm-info@iis.fraunhofer.de
|
|
#include "aacdec_tns.h"
|
|
#include "FDK_bitstream.h"
|
|
|
|
-#include "conceal.h"
|
|
-
|
|
-#include "rvlc.h"
|
|
-
|
|
-#include "aacdec_hcr.h"
|
|
-
|
|
#include "usacdec_lpd.h"
|
|
#include "usacdec_fac.h"
|
|
|
|
@@ -376,9 +370,6 @@ void CChannelElement_Decode(
|
|
->pCpeStaticData->jointStereoPersistentData.clearSpectralCoeffs = 0;
|
|
}
|
|
}
|
|
-
|
|
- CRvlc_ElementCheck(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
|
|
- flags, el_channels);
|
|
}
|
|
|
|
void CChannel_CodebookTableInit(
|
|
@@ -596,8 +587,8 @@ AAC_DECODER_ERROR CChannelElement_Read(
|
|
|
|
case scale_factor_data:
|
|
if (flags & AC_ER_RVLC) {
|
|
- /* read RVLC data from bitstream (error sens. cat. 1) */
|
|
- CRvlc_Read(pAacDecoderChannelInfo[ch], hBs);
|
|
+ /* RVLC not supported */
|
|
+ error = AAC_DEC_DECODE_FRAME_ERROR;
|
|
} else {
|
|
error = CBlock_ReadScaleFactorData(pAacDecoderChannelInfo[ch], hBs,
|
|
flags);
|
|
@@ -730,15 +721,13 @@ AAC_DECODER_ERROR CChannelElement_Read(
|
|
} break;
|
|
case esc2_rvlc:
|
|
if (flags & AC_ER_RVLC) {
|
|
- CRvlc_Decode(pAacDecoderChannelInfo[ch],
|
|
- pAacDecoderStaticChannelInfo[ch], hBs);
|
|
+ error = AAC_DEC_UNSUPPORTED_FORMAT;
|
|
}
|
|
break;
|
|
|
|
case esc1_hcr:
|
|
if (flags & AC_ER_HCR) {
|
|
- CHcr_Read(hBs, pAacDecoderChannelInfo[ch],
|
|
- numberOfChannels == 2 ? ID_CPE : ID_SCE);
|
|
+ error = AAC_DEC_UNSUPPORTED_FORMAT;
|
|
}
|
|
break;
|
|
|
|
--- a/libAACdec/src/channelinfo.h
|
|
+++ b/libAACdec/src/channelinfo.h
|
|
@@ -117,17 +117,12 @@ amm-info@iis.fraunhofer.de
|
|
|
|
#include "aacdec_pns.h"
|
|
|
|
-#include "aacdec_hcr_types.h"
|
|
-#include "rvlc_info.h"
|
|
-
|
|
#include "usacdec_acelp.h"
|
|
#include "usacdec_const.h"
|
|
#include "usacdec_rom.h"
|
|
|
|
#include "ac_arith_coder.h"
|
|
|
|
-#include "conceal_types.h"
|
|
-
|
|
#include "aacdec_drc_types.h"
|
|
|
|
#define WB_SECTION_SIZE (1024 * 2)
|
|
@@ -257,7 +252,6 @@ typedef struct {
|
|
ULONG nfRandomSeed; /* seed value for USAC noise filling random generator */
|
|
|
|
CDrcChannelData drcData;
|
|
- CConcealmentInfo concealmentInfo;
|
|
|
|
CpePersistentData *pCpeStaticData;
|
|
|
|
@@ -280,11 +274,6 @@ typedef struct {
|
|
shouldBeUnion {
|
|
struct {
|
|
CPulseData PulseData;
|
|
- SHORT aNumLineInSec4Hcr[MAX_SFB_HCR]; /* needed once for all channels
|
|
- except for Drm syntax */
|
|
- UCHAR
|
|
- aCodeBooks4Hcr[MAX_SFB_HCR]; /* needed once for all channels except for
|
|
- Drm syntax. Same as "aCodeBook" ? */
|
|
SHORT lenOfReorderedSpectralData;
|
|
SCHAR lenOfLongestCodeword;
|
|
SCHAR numberSection;
|
|
@@ -325,17 +314,6 @@ typedef struct {
|
|
|
|
CJointStereoData jointStereoData; /* One for one element */
|
|
|
|
- shouldBeUnion {
|
|
- struct {
|
|
- CErHcrInfo erHcrInfo;
|
|
- CErRvlcInfo erRvlcInfo;
|
|
- SHORT aRvlcScfEsc[RVLC_MAX_SFB]; /* needed once for all channels */
|
|
- SHORT aRvlcScfFwd[RVLC_MAX_SFB]; /* needed once for all channels */
|
|
- SHORT aRvlcScfBwd[RVLC_MAX_SFB]; /* needed once for all channels */
|
|
- } aac;
|
|
- }
|
|
- overlay;
|
|
-
|
|
} CAacDecoderCommonData;
|
|
|
|
typedef struct {
|
|
--- a/libAACdec/src/conceal.cpp
|
|
+++ /dev/null
|
|
@@ -1,2095 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s): Josef Hoepfl
|
|
-
|
|
- Description: independent channel concealment
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-/*!
|
|
- \page concealment AAC core concealment
|
|
-
|
|
- This AAC core implementation includes a concealment function, which can be
|
|
- enabled using the several defines during compilation.
|
|
-
|
|
- There are various tests inside the core, starting with simple CRC tests and
|
|
- ending in a variety of plausibility checks. If such a check indicates an
|
|
- invalid bitstream, then concealment is applied.
|
|
-
|
|
- Concealment is also applied when the calling main program indicates a
|
|
- distorted or missing data frame using the frameOK flag. This is used for error
|
|
- detection on the transport layer. (See below)
|
|
-
|
|
- There are three concealment-modes:
|
|
-
|
|
- 1) Muting: The spectral data is simply set to zero in case of an detected
|
|
- error.
|
|
-
|
|
- 2) Noise substitution: In case of an detected error, concealment copies the
|
|
- last frame and adds attenuates the spectral data. For this mode you have to
|
|
- set the #CONCEAL_NOISE define. Noise substitution adds no additional delay.
|
|
-
|
|
- 3) Interpolation: The interpolation routine swaps the spectral data from the
|
|
- previous and the current frame just before the final frequency to time
|
|
- conversion. In case a single frame is corrupted, concealmant interpolates
|
|
- between the last good and the first good frame to create the spectral data for
|
|
- the missing frame. If multiple frames are corrupted, concealment implements
|
|
- first a fade out based on slightly modified spectral values from the last good
|
|
- frame. As soon as good frames are available, concealmant fades in the new
|
|
- spectral data. For this mode you have to set the #CONCEAL_INTER define. Note
|
|
- that in this case, you also need to set #SBR_BS_DELAY_ENABLE, which basically
|
|
- adds approriate delay in the SBR decoder. Note that the
|
|
- Interpolating-Concealment increases the delay of your decoder by one frame and
|
|
- that it does require additional resources such as memory and computational
|
|
- complexity.
|
|
-
|
|
- <h2>How concealment can be used with errors on the transport layer</h2>
|
|
-
|
|
- Many errors can or have to be detected on the transport layer. For example in
|
|
- IP based systems packet loss can occur. The transport protocol used should
|
|
- indicate such packet loss by inserting an empty frame with frameOK=0.
|
|
-*/
|
|
-
|
|
-#include "conceal.h"
|
|
-
|
|
-#include "aac_rom.h"
|
|
-#include "genericStds.h"
|
|
-
|
|
-/* PNS (of block) */
|
|
-#include "aacdec_pns.h"
|
|
-#include "block.h"
|
|
-
|
|
-#define CONCEAL_DFLT_COMF_NOISE_LEVEL (0x100000)
|
|
-
|
|
-#define CONCEAL_NOT_DEFINED ((UCHAR)-1)
|
|
-
|
|
-/* default settings */
|
|
-#define CONCEAL_DFLT_FADEOUT_FRAMES (6)
|
|
-#define CONCEAL_DFLT_FADEIN_FRAMES (5)
|
|
-#define CONCEAL_DFLT_MUTE_RELEASE_FRAMES (0)
|
|
-
|
|
-#define CONCEAL_DFLT_FADE_FACTOR (0.707106781186548f) /* 1/sqrt(2) */
|
|
-
|
|
-/* some often used constants: */
|
|
-#define FIXP_ZERO FL2FXCONST_DBL(0.0f)
|
|
-#define FIXP_ONE FL2FXCONST_DBL(1.0f)
|
|
-#define FIXP_FL_CORRECTION FL2FXCONST_DBL(0.53333333333333333f)
|
|
-
|
|
-/* For parameter conversion */
|
|
-#define CONCEAL_PARAMETER_BITS (8)
|
|
-#define CONCEAL_MAX_QUANT_FACTOR ((1 << CONCEAL_PARAMETER_BITS) - 1)
|
|
-/*#define CONCEAL_MIN_ATTENUATION_FACTOR_025 ( FL2FXCONST_DBL(0.971627951577106174) )*/ /* -0.25 dB */
|
|
-#define CONCEAL_MIN_ATTENUATION_FACTOR_025_LD \
|
|
- FL2FXCONST_DBL(-0.041524101186092029596853445212299)
|
|
-/*#define CONCEAL_MIN_ATTENUATION_FACTOR_050 ( FL2FXCONST_DBL(0.944060876285923380) )*/ /* -0.50 dB */
|
|
-#define CONCEAL_MIN_ATTENUATION_FACTOR_050_LD \
|
|
- FL2FXCONST_DBL(-0.083048202372184059253597008145293)
|
|
-
|
|
-typedef enum {
|
|
- CConcealment_NoExpand,
|
|
- CConcealment_Expand,
|
|
- CConcealment_Compress
|
|
-} CConcealmentExpandType;
|
|
-
|
|
-static const FIXP_SGL facMod4Table[4] = {
|
|
- FL2FXCONST_SGL(0.500000000f), /* FIXP_SGL(0x4000), 2^-(1-0,00) */
|
|
- FL2FXCONST_SGL(0.594603558f), /* FIXP_SGL(0x4c1b), 2^-(1-0,25) */
|
|
- FL2FXCONST_SGL(0.707106781f), /* FIXP_SGL(0x5a82), 2^-(1-0,50) */
|
|
- FL2FXCONST_SGL(0.840896415f) /* FIXP_SGL(0x6ba2) 2^-(1-0,75) */
|
|
-};
|
|
-
|
|
-static void CConcealment_CalcBandEnergy(
|
|
- FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo,
|
|
- const int blockType, CConcealmentExpandType ex, int *sfbEnergy);
|
|
-
|
|
-static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
|
|
- SHORT *pSpecScalePrev,
|
|
- SHORT *pSpecScaleAct,
|
|
- SHORT *pSpecScaleOut, int *enPrv,
|
|
- int *enAct, int sfbCnt,
|
|
- const SHORT *pSfbOffset);
|
|
-
|
|
-static int CConcealment_ApplyInter(
|
|
- CConcealmentInfo *pConcealmentInfo,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
|
|
- const int improveTonal, const int frameOk, const int mute_release_active);
|
|
-
|
|
-static int CConcealment_ApplyNoise(
|
|
- CConcealmentInfo *pConcealmentInfo,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
|
- const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
|
|
- const UINT flags);
|
|
-
|
|
-static void CConcealment_UpdateState(
|
|
- CConcealmentInfo *pConcealmentInfo, int frameOk,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
|
- const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo);
|
|
-
|
|
-static void CConcealment_ApplyRandomSign(int iRandomPhase, FIXP_DBL *spec,
|
|
- int samplesPerFrame);
|
|
-
|
|
-/* TimeDomainFading */
|
|
-static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
|
|
- FIXP_DBL fadeStop, FIXP_PCM *pcmdata);
|
|
-static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
|
|
- int *fadingSteps,
|
|
- FIXP_DBL fadeStop,
|
|
- FIXP_DBL fadeStart,
|
|
- TDfadingType fadingType);
|
|
-static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps);
|
|
-
|
|
-/* Streamline the state machine */
|
|
-static int CConcealment_ApplyFadeOut(
|
|
- int mode, CConcealmentInfo *pConcealmentInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
|
- const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo);
|
|
-
|
|
-static int CConcealment_TDNoise_Random(ULONG *seed);
|
|
-static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
|
|
- const int len, FIXP_PCM *const pcmdata);
|
|
-
|
|
-static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) {
|
|
- BLOCK_TYPE newWinSeq = BLOCK_LONG;
|
|
-
|
|
- /* Try to have only long blocks */
|
|
- if (prevWinSeq == BLOCK_START || prevWinSeq == BLOCK_SHORT) {
|
|
- newWinSeq = BLOCK_STOP;
|
|
- }
|
|
-
|
|
- return (newWinSeq);
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Init common concealment information data
|
|
-
|
|
- \param pConcealCommonData Pointer to the concealment common data structure.
|
|
-*/
|
|
-void CConcealment_InitCommonData(CConcealParams *pConcealCommonData) {
|
|
- if (pConcealCommonData != NULL) {
|
|
- int i;
|
|
-
|
|
- /* Set default error concealment technique */
|
|
- pConcealCommonData->method = ConcealMethodInter;
|
|
-
|
|
- pConcealCommonData->numFadeOutFrames = CONCEAL_DFLT_FADEOUT_FRAMES;
|
|
- pConcealCommonData->numFadeInFrames = CONCEAL_DFLT_FADEIN_FRAMES;
|
|
- pConcealCommonData->numMuteReleaseFrames = CONCEAL_DFLT_MUTE_RELEASE_FRAMES;
|
|
-
|
|
- pConcealCommonData->comfortNoiseLevel =
|
|
- (FIXP_DBL)CONCEAL_DFLT_COMF_NOISE_LEVEL;
|
|
-
|
|
- /* Init fade factors (symetric) */
|
|
- pConcealCommonData->fadeOutFactor[0] =
|
|
- FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR);
|
|
- pConcealCommonData->fadeInFactor[0] = pConcealCommonData->fadeOutFactor[0];
|
|
-
|
|
- for (i = 1; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
|
|
- pConcealCommonData->fadeOutFactor[i] =
|
|
- FX_DBL2FX_SGL(fMult(pConcealCommonData->fadeOutFactor[i - 1],
|
|
- FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR)));
|
|
- pConcealCommonData->fadeInFactor[i] =
|
|
- pConcealCommonData->fadeOutFactor[i];
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Get current concealment method.
|
|
-
|
|
- \param pConcealCommonData Pointer to common concealment data (for all
|
|
- channels)
|
|
-*/
|
|
-CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData) {
|
|
- CConcealmentMethod method = ConcealMethodNone;
|
|
-
|
|
- if (pConcealCommonData != NULL) {
|
|
- method = pConcealCommonData->method;
|
|
- }
|
|
-
|
|
- return (method);
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Init concealment information for each channel
|
|
-
|
|
- \param pConcealChannelInfo Pointer to the channel related concealment info
|
|
- structure to be initialized. \param pConcealCommonData Pointer to common
|
|
- concealment data (for all channels) \param initRenderMode Initial render
|
|
- mode to be set for the current channel. \param samplesPerFrame The number
|
|
- of samples per frame.
|
|
-*/
|
|
-void CConcealment_InitChannelData(CConcealmentInfo *pConcealChannelInfo,
|
|
- CConcealParams *pConcealCommonData,
|
|
- AACDEC_RENDER_MODE initRenderMode,
|
|
- int samplesPerFrame) {
|
|
- int i;
|
|
- pConcealChannelInfo->TDNoiseSeed = 0;
|
|
- FDKmemclear(pConcealChannelInfo->TDNoiseStates,
|
|
- sizeof(pConcealChannelInfo->TDNoiseStates));
|
|
- pConcealChannelInfo->TDNoiseCoef[0] = FL2FXCONST_SGL(0.05f);
|
|
- pConcealChannelInfo->TDNoiseCoef[1] = FL2FXCONST_SGL(0.5f);
|
|
- pConcealChannelInfo->TDNoiseCoef[2] = FL2FXCONST_SGL(0.45f);
|
|
-
|
|
- pConcealChannelInfo->pConcealParams = pConcealCommonData;
|
|
-
|
|
- pConcealChannelInfo->lastRenderMode = initRenderMode;
|
|
-
|
|
- pConcealChannelInfo->windowShape = CONCEAL_NOT_DEFINED;
|
|
- pConcealChannelInfo->windowSequence = BLOCK_LONG; /* default type */
|
|
- pConcealChannelInfo->lastWinGrpLen = 1;
|
|
-
|
|
- pConcealChannelInfo->concealState = ConcealState_Ok;
|
|
-
|
|
- FDKmemclear(pConcealChannelInfo->spectralCoefficient,
|
|
- 1024 * sizeof(FIXP_CNCL));
|
|
-
|
|
- for (i = 0; i < 8; i++) {
|
|
- pConcealChannelInfo->specScale[i] = 0;
|
|
- }
|
|
-
|
|
- pConcealChannelInfo->iRandomPhase = 0;
|
|
-
|
|
- pConcealChannelInfo->prevFrameOk[0] = 1;
|
|
- pConcealChannelInfo->prevFrameOk[1] = 1;
|
|
-
|
|
- pConcealChannelInfo->cntFadeFrames = 0;
|
|
- pConcealChannelInfo->cntValidFrames = 0;
|
|
- pConcealChannelInfo->fade_old = (FIXP_DBL)MAXVAL_DBL;
|
|
- pConcealChannelInfo->winGrpOffset[0] = 0;
|
|
- pConcealChannelInfo->winGrpOffset[1] = 0;
|
|
- pConcealChannelInfo->attGrpOffset[0] = 0;
|
|
- pConcealChannelInfo->attGrpOffset[1] = 0;
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Set error concealment parameters
|
|
-
|
|
- \param concealParams
|
|
- \param method
|
|
- \param fadeOutSlope
|
|
- \param fadeInSlope
|
|
- \param muteRelease
|
|
- \param comfNoiseLevel
|
|
-*/
|
|
-AAC_DECODER_ERROR
|
|
-CConcealment_SetParams(CConcealParams *concealParams, int method,
|
|
- int fadeOutSlope, int fadeInSlope, int muteRelease,
|
|
- FIXP_DBL comfNoiseLevel) {
|
|
- /* set concealment technique */
|
|
- if (method != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
|
|
- switch ((CConcealmentMethod)method) {
|
|
- case ConcealMethodMute:
|
|
- case ConcealMethodNoise:
|
|
- case ConcealMethodInter:
|
|
- /* Be sure to enable delay adjustment of SBR decoder! */
|
|
- if (concealParams == NULL) {
|
|
- return AAC_DEC_INVALID_HANDLE;
|
|
- } else {
|
|
- /* set param */
|
|
- concealParams->method = (CConcealmentMethod)method;
|
|
- }
|
|
- break;
|
|
-
|
|
- default:
|
|
- return AAC_DEC_SET_PARAM_FAIL;
|
|
- }
|
|
- }
|
|
-
|
|
- /* set number of frames for fade-out slope */
|
|
- if (fadeOutSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
|
|
- if ((fadeOutSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeOutSlope >= 0)) {
|
|
- if (concealParams == NULL) {
|
|
- return AAC_DEC_INVALID_HANDLE;
|
|
- } else {
|
|
- /* set param */
|
|
- concealParams->numFadeOutFrames = fadeOutSlope;
|
|
- }
|
|
- } else {
|
|
- return AAC_DEC_SET_PARAM_FAIL;
|
|
- }
|
|
- }
|
|
-
|
|
- /* set number of frames for fade-in slope */
|
|
- if (fadeInSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
|
|
- if ((fadeInSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeInSlope >= 0)) {
|
|
- if (concealParams == NULL) {
|
|
- return AAC_DEC_INVALID_HANDLE;
|
|
- } else {
|
|
- /* set param */
|
|
- concealParams->numFadeInFrames = fadeInSlope;
|
|
- }
|
|
- } else {
|
|
- return AAC_DEC_SET_PARAM_FAIL;
|
|
- }
|
|
- }
|
|
-
|
|
- /* set number of error-free frames after which the muting will be released */
|
|
- if (muteRelease != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
|
|
- if ((muteRelease < (CONCEAL_MAX_NUM_FADE_FACTORS << 1)) &&
|
|
- (muteRelease >= 0)) {
|
|
- if (concealParams == NULL) {
|
|
- return AAC_DEC_INVALID_HANDLE;
|
|
- } else {
|
|
- /* set param */
|
|
- concealParams->numMuteReleaseFrames = muteRelease;
|
|
- }
|
|
- } else {
|
|
- return AAC_DEC_SET_PARAM_FAIL;
|
|
- }
|
|
- }
|
|
-
|
|
- /* set confort noise level which will be inserted while in state 'muting' */
|
|
- if (comfNoiseLevel != (FIXP_DBL)AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
|
|
- if ((comfNoiseLevel < (FIXP_DBL)0) ||
|
|
- (comfNoiseLevel > (FIXP_DBL)MAXVAL_DBL)) {
|
|
- return AAC_DEC_SET_PARAM_FAIL;
|
|
- }
|
|
- if (concealParams == NULL) {
|
|
- return AAC_DEC_INVALID_HANDLE;
|
|
- } else {
|
|
- concealParams->comfortNoiseLevel = (FIXP_DBL)comfNoiseLevel;
|
|
- }
|
|
- }
|
|
-
|
|
- return (AAC_DEC_OK);
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Set fade-out/in attenuation factor vectors
|
|
-
|
|
- \param concealParams
|
|
- \param fadeOutAttenuationVector
|
|
- \param fadeInAttenuationVector
|
|
-
|
|
- \return 0 if OK all other values indicate errors
|
|
-*/
|
|
-AAC_DECODER_ERROR
|
|
-CConcealment_SetAttenuation(CConcealParams *concealParams,
|
|
- const SHORT *fadeOutAttenuationVector,
|
|
- const SHORT *fadeInAttenuationVector) {
|
|
- if ((fadeOutAttenuationVector == NULL) && (fadeInAttenuationVector == NULL)) {
|
|
- return AAC_DEC_SET_PARAM_FAIL;
|
|
- }
|
|
-
|
|
- /* Fade-out factors */
|
|
- if (fadeOutAttenuationVector != NULL) {
|
|
- int i;
|
|
-
|
|
- /* check quantized factors first */
|
|
- for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
|
|
- if ((fadeOutAttenuationVector[i] < 0) ||
|
|
- (fadeOutAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) {
|
|
- return AAC_DEC_SET_PARAM_FAIL;
|
|
- }
|
|
- }
|
|
- if (concealParams == NULL) {
|
|
- return AAC_DEC_INVALID_HANDLE;
|
|
- }
|
|
-
|
|
- /* now dequantize factors */
|
|
- for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
|
|
- concealParams->fadeOutFactor[i] =
|
|
- FX_DBL2FX_SGL(fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0,
|
|
- (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0 / 2.0) >>
|
|
- (CONCEAL_PARAMETER_BITS - 1)) *
|
|
- (INT)fadeOutAttenuationVector[i]),
|
|
- CONCEAL_PARAMETER_BITS));
|
|
- }
|
|
- }
|
|
-
|
|
- /* Fade-in factors */
|
|
- if (fadeInAttenuationVector != NULL) {
|
|
- int i;
|
|
-
|
|
- /* check quantized factors first */
|
|
- for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
|
|
- if ((fadeInAttenuationVector[i] < 0) ||
|
|
- (fadeInAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) {
|
|
- return AAC_DEC_SET_PARAM_FAIL;
|
|
- }
|
|
- }
|
|
- if (concealParams == NULL) {
|
|
- return AAC_DEC_INVALID_HANDLE;
|
|
- }
|
|
-
|
|
- /* now dequantize factors */
|
|
- for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
|
|
- concealParams->fadeInFactor[i] = FX_DBL2FX_SGL(
|
|
- fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0,
|
|
- (FIXP_DBL)((INT)(FIXP_ONE >> CONCEAL_PARAMETER_BITS) *
|
|
- (INT)fadeInAttenuationVector[i]),
|
|
- CONCEAL_PARAMETER_BITS));
|
|
- }
|
|
- }
|
|
-
|
|
- return (AAC_DEC_OK);
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Get state of concealment module.
|
|
-
|
|
- \param pConcealChannelInfo
|
|
-
|
|
- \return Concealment state.
|
|
-*/
|
|
-CConcealmentState CConcealment_GetState(CConcealmentInfo *pConcealChannelInfo) {
|
|
- CConcealmentState state = ConcealState_Ok;
|
|
-
|
|
- if (pConcealChannelInfo != NULL) {
|
|
- state = pConcealChannelInfo->concealState;
|
|
- }
|
|
-
|
|
- return (state);
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Store data for concealment techniques applied later
|
|
-
|
|
- Interface function to store data for different concealment strategies
|
|
- */
|
|
-void CConcealment_Store(
|
|
- CConcealmentInfo *hConcealmentInfo,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
|
|
- UCHAR nbDiv = NB_DIV;
|
|
-
|
|
- if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
|
|
- pAacDecoderChannelInfo->data.usac.mod[nbDiv - 1] == 0))
|
|
-
|
|
- {
|
|
- FIXP_DBL *pSpectralCoefficient =
|
|
- SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
|
|
- SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
|
|
- CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
|
|
-
|
|
- SHORT tSpecScale[8];
|
|
- UCHAR tWindowShape;
|
|
- BLOCK_TYPE tWindowSequence;
|
|
-
|
|
- /* store old window infos for swapping */
|
|
- tWindowSequence = hConcealmentInfo->windowSequence;
|
|
- tWindowShape = hConcealmentInfo->windowShape;
|
|
-
|
|
- /* store old scale factors for swapping */
|
|
- FDKmemcpy(tSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT));
|
|
-
|
|
- /* store new window infos */
|
|
- hConcealmentInfo->windowSequence = GetWindowSequence(pIcsInfo);
|
|
- hConcealmentInfo->windowShape = GetWindowShape(pIcsInfo);
|
|
- hConcealmentInfo->lastWinGrpLen =
|
|
- *(GetWindowGroupLengthTable(pIcsInfo) + GetWindowGroups(pIcsInfo) - 1);
|
|
-
|
|
- /* store new scale factors */
|
|
- FDKmemcpy(hConcealmentInfo->specScale, pSpecScale, 8 * sizeof(SHORT));
|
|
-
|
|
- if (hConcealmentInfo->pConcealParams->method < ConcealMethodInter) {
|
|
- /* store new spectral bins */
|
|
-#if (CNCL_FRACT_BITS == DFRACT_BITS)
|
|
- FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpectralCoefficient,
|
|
- 1024 * sizeof(FIXP_CNCL));
|
|
-#else
|
|
- FIXP_CNCL *RESTRICT pCncl =
|
|
- &hConcealmentInfo->spectralCoefficient[1024 - 1];
|
|
- FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
|
|
- int i;
|
|
- for (i = 1024; i != 0; i--) {
|
|
- *pCncl-- = FX_DBL2FX_CNCL(*pSpec--);
|
|
- }
|
|
-#endif
|
|
- } else {
|
|
- /* swap spectral data */
|
|
-#if (FIXP_CNCL == FIXP_DBL)
|
|
- C_ALLOC_SCRATCH_START(pSpecTmp, FIXP_DBL, 1024);
|
|
- FDKmemcpy(pSpecTmp, pSpectralCoefficient, 1024 * sizeof(FIXP_DBL));
|
|
- FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient,
|
|
- 1024 * sizeof(FIXP_DBL));
|
|
- FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpecTmp,
|
|
- 1024 * sizeof(FIXP_DBL));
|
|
- C_ALLOC_SCRATCH_END(pSpecTmp, FIXP_DBL, 1024);
|
|
-#else
|
|
- FIXP_CNCL *RESTRICT pCncl =
|
|
- &hConcealmentInfo->spectralCoefficient[1024 - 1];
|
|
- FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
|
|
- FIXP_DBL tSpec;
|
|
-
|
|
- for (int i = 1024; i != 0; i--) {
|
|
- tSpec = *pSpec;
|
|
- *pSpec-- = FX_CNCL2FX_DBL(*pCncl);
|
|
- *pCncl-- = FX_DBL2FX_CNCL(tSpec);
|
|
- }
|
|
-#endif
|
|
-
|
|
- /* complete swapping of window infos */
|
|
- pIcsInfo->WindowSequence = tWindowSequence;
|
|
- pIcsInfo->WindowShape = tWindowShape;
|
|
-
|
|
- /* complete swapping of scale factors */
|
|
- FDKmemcpy(pSpecScale, tSpecScale, 8 * sizeof(SHORT));
|
|
- }
|
|
- }
|
|
-
|
|
- if (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD) {
|
|
- /* Store LSF4 */
|
|
- FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf,
|
|
- sizeof(hConcealmentInfo->lsf4));
|
|
- /* Store TCX gain */
|
|
- hConcealmentInfo->last_tcx_gain =
|
|
- pAacDecoderStaticChannelInfo->last_tcx_gain;
|
|
- hConcealmentInfo->last_tcx_gain_e =
|
|
- pAacDecoderStaticChannelInfo->last_tcx_gain_e;
|
|
- }
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Apply concealment
|
|
-
|
|
- Interface function to different concealment strategies
|
|
- */
|
|
-int CConcealment_Apply(
|
|
- CConcealmentInfo *hConcealmentInfo,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
|
- const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
|
|
- const UCHAR lastLpdMode, const int frameOk, const UINT flags) {
|
|
- int appliedProcessing = 0;
|
|
- const int mute_release_active =
|
|
- frameOk && (hConcealmentInfo->concealState >= ConcealState_Mute) &&
|
|
- (hConcealmentInfo->cntValidFrames + 1 <=
|
|
- hConcealmentInfo->pConcealParams->numMuteReleaseFrames);
|
|
-
|
|
- if (hConcealmentInfo->windowShape == CONCEAL_NOT_DEFINED) {
|
|
- /* Initialize window_shape with same value as in the current (parsed) frame.
|
|
- Because section 4.6.11.3.2 (Windowing and block switching) of ISO/IEC
|
|
- 14496-3:2009 says: For the first raw_data_block() to be decoded the
|
|
- window_shape of the left and right half of the window are identical. */
|
|
- hConcealmentInfo->windowShape = pAacDecoderChannelInfo->icsInfo.WindowShape;
|
|
- }
|
|
-
|
|
- if (frameOk && !mute_release_active) {
|
|
- /* Update render mode if frameOk except for ongoing mute release state. */
|
|
- hConcealmentInfo->lastRenderMode =
|
|
- (SCHAR)pAacDecoderChannelInfo->renderMode;
|
|
-
|
|
- /* Rescue current data for concealment in future frames */
|
|
- CConcealment_Store(hConcealmentInfo, pAacDecoderChannelInfo,
|
|
- pAacDecoderStaticChannelInfo);
|
|
- /* Reset index to random sign vector to make sign calculation frame agnostic
|
|
- (only depends on number of subsequently concealed spectral blocks) */
|
|
- hConcealmentInfo->iRandomPhase = 0;
|
|
- } else {
|
|
- if (hConcealmentInfo->lastRenderMode == AACDEC_RENDER_INVALID) {
|
|
- hConcealmentInfo->lastRenderMode = AACDEC_RENDER_IMDCT;
|
|
- }
|
|
- pAacDecoderChannelInfo->renderMode =
|
|
- (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode;
|
|
- }
|
|
-
|
|
- /* hand current frame status to the state machine */
|
|
- CConcealment_UpdateState(hConcealmentInfo, frameOk,
|
|
- pAacDecoderStaticChannelInfo, samplesPerFrame,
|
|
- pAacDecoderChannelInfo);
|
|
-
|
|
- {
|
|
- if (!frameOk && pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_IMDCT) {
|
|
- /* LPC extrapolation */
|
|
- CLpc_Conceal(pAacDecoderChannelInfo->data.usac.lsp_coeff,
|
|
- pAacDecoderStaticChannelInfo->lpc4_lsf,
|
|
- pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
|
|
- hConcealmentInfo->lastRenderMode == AACDEC_RENDER_IMDCT);
|
|
- FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf,
|
|
- sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf));
|
|
- }
|
|
-
|
|
- /* Create data for signal rendering according to the selected concealment
|
|
- * method and decoder operating mode. */
|
|
-
|
|
- if ((!frameOk || mute_release_active) &&
|
|
- (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD)) {
|
|
- /* Restore old LSF4 */
|
|
- FDKmemcpy(pAacDecoderStaticChannelInfo->lpc4_lsf, hConcealmentInfo->lsf4,
|
|
- sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf));
|
|
- /* Restore old TCX gain */
|
|
- pAacDecoderStaticChannelInfo->last_tcx_gain =
|
|
- hConcealmentInfo->last_tcx_gain;
|
|
- pAacDecoderStaticChannelInfo->last_tcx_gain_e =
|
|
- hConcealmentInfo->last_tcx_gain_e;
|
|
- }
|
|
-
|
|
- if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
|
|
- pAacDecoderStaticChannelInfo->last_lpd_mode == 0)) {
|
|
- switch (hConcealmentInfo->pConcealParams->method) {
|
|
- default:
|
|
- case ConcealMethodMute:
|
|
- if (!frameOk) {
|
|
- /* Mute spectral data in case of errors */
|
|
- FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient,
|
|
- samplesPerFrame * sizeof(FIXP_DBL));
|
|
- /* Set last window shape */
|
|
- pAacDecoderChannelInfo->icsInfo.WindowShape =
|
|
- hConcealmentInfo->windowShape;
|
|
- appliedProcessing = 1;
|
|
- }
|
|
- break;
|
|
-
|
|
- case ConcealMethodNoise:
|
|
- /* Noise substitution error concealment technique */
|
|
- appliedProcessing = CConcealment_ApplyNoise(
|
|
- hConcealmentInfo, pAacDecoderChannelInfo,
|
|
- pAacDecoderStaticChannelInfo, pSamplingRateInfo, samplesPerFrame,
|
|
- flags);
|
|
- break;
|
|
-
|
|
- case ConcealMethodInter:
|
|
- /* Energy interpolation concealment based on 3GPP */
|
|
- appliedProcessing = CConcealment_ApplyInter(
|
|
- hConcealmentInfo, pAacDecoderChannelInfo, pSamplingRateInfo,
|
|
- samplesPerFrame, 0, /* don't use tonal improvement */
|
|
- frameOk, mute_release_active);
|
|
- break;
|
|
- }
|
|
- } else if (!frameOk || mute_release_active) {
|
|
- /* simply restore the buffer */
|
|
- FIXP_DBL *pSpectralCoefficient =
|
|
- SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
|
|
- SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
|
|
- CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
|
|
-#if (CNCL_FRACT_BITS != DFRACT_BITS)
|
|
- FIXP_CNCL *RESTRICT pCncl =
|
|
- &hConcealmentInfo->spectralCoefficient[1024 - 1];
|
|
- FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
|
|
- int i;
|
|
-#endif
|
|
-
|
|
- /* restore window infos (gri) do we need that? */
|
|
- pIcsInfo->WindowSequence = hConcealmentInfo->windowSequence;
|
|
- pIcsInfo->WindowShape = hConcealmentInfo->windowShape;
|
|
-
|
|
- if (hConcealmentInfo->concealState != ConcealState_Mute) {
|
|
- /* restore scale factors */
|
|
- FDKmemcpy(pSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT));
|
|
-
|
|
- /* restore spectral bins */
|
|
-#if (CNCL_FRACT_BITS == DFRACT_BITS)
|
|
- FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient,
|
|
- 1024 * sizeof(FIXP_DBL));
|
|
-#else
|
|
- for (i = 1024; i != 0; i--) {
|
|
- *pSpec-- = FX_CNCL2FX_DBL(*pCncl--);
|
|
- }
|
|
-#endif
|
|
- } else {
|
|
- /* clear scale factors */
|
|
- FDKmemclear(pSpecScale, 8 * sizeof(SHORT));
|
|
-
|
|
- /* clear buffer */
|
|
- FDKmemclear(pSpectralCoefficient, 1024 * sizeof(FIXP_CNCL));
|
|
- }
|
|
- }
|
|
- }
|
|
- /* update history */
|
|
- hConcealmentInfo->prevFrameOk[0] = hConcealmentInfo->prevFrameOk[1];
|
|
- hConcealmentInfo->prevFrameOk[1] = frameOk;
|
|
-
|
|
- return mute_release_active ? -1 : appliedProcessing;
|
|
-}
|
|
-
|
|
-/*!
|
|
-\brief Apply concealment noise substitution
|
|
-
|
|
- In case of frame lost this function produces a noisy frame with respect to the
|
|
- energies values of past frame.
|
|
- */
|
|
-static int CConcealment_ApplyNoise(
|
|
- CConcealmentInfo *pConcealmentInfo,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
|
- const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
|
|
- const UINT flags) {
|
|
- FIXP_DBL *pSpectralCoefficient =
|
|
- SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
|
|
- CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
|
|
-
|
|
- int appliedProcessing = 0;
|
|
-
|
|
- FDK_ASSERT(pConcealmentInfo != NULL);
|
|
- FDK_ASSERT((samplesPerFrame >= 120) && (samplesPerFrame <= 1024));
|
|
-
|
|
- switch (pConcealmentInfo->concealState) {
|
|
- case ConcealState_Ok:
|
|
- /* Nothing to do here! */
|
|
- break;
|
|
-
|
|
- case ConcealState_Single:
|
|
- case ConcealState_FadeOut:
|
|
- appliedProcessing = CConcealment_ApplyFadeOut(
|
|
- /*mode =*/1, pConcealmentInfo, pAacDecoderStaticChannelInfo,
|
|
- samplesPerFrame, pAacDecoderChannelInfo);
|
|
- break;
|
|
-
|
|
- case ConcealState_Mute: {
|
|
- /* set dummy window parameters */
|
|
- pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */
|
|
- pIcsInfo->WindowShape =
|
|
- pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape
|
|
- (required for F/T transform) */
|
|
- pIcsInfo->WindowSequence =
|
|
- CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
|
|
- pConcealmentInfo->windowSequence =
|
|
- pIcsInfo->WindowSequence; /* Store for next frame
|
|
- (spectrum in concealment
|
|
- buffer can't be used at
|
|
- all) */
|
|
-
|
|
- /* mute spectral data */
|
|
- FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
|
|
- FDKmemclear(pConcealmentInfo->spectralCoefficient,
|
|
- samplesPerFrame * sizeof(FIXP_DBL));
|
|
-
|
|
- appliedProcessing = 1;
|
|
- } break;
|
|
-
|
|
- case ConcealState_FadeIn: {
|
|
- /* TimeDomainFading: */
|
|
- /* Attenuation of signal is done in CConcealment_TDFading() */
|
|
-
|
|
- appliedProcessing = 1;
|
|
- } break;
|
|
-
|
|
- default:
|
|
- /* we shouldn't come here anyway */
|
|
- FDK_ASSERT(0);
|
|
- break;
|
|
- }
|
|
-
|
|
- return appliedProcessing;
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Apply concealment interpolation
|
|
-
|
|
- The function swaps the data from the current and the previous frame. If an
|
|
- error has occured, frame interpolation is performed to restore the missing
|
|
- frame. In case of multiple faulty frames, fade-in and fade-out is applied.
|
|
-*/
|
|
-static int CConcealment_ApplyInter(
|
|
- CConcealmentInfo *pConcealmentInfo,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
|
|
- const int improveTonal, const int frameOk, const int mute_release_active) {
|
|
-#if defined(FDK_ASSERT_ENABLE)
|
|
- CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
|
|
-#endif
|
|
-
|
|
- FIXP_DBL *pSpectralCoefficient =
|
|
- SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
|
|
- CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
|
|
- SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
|
|
-
|
|
- int sfbEnergyPrev[64];
|
|
- int sfbEnergyAct[64];
|
|
-
|
|
- int i, appliedProcessing = 0;
|
|
-
|
|
- /* clear/init */
|
|
- FDKmemclear(sfbEnergyPrev, 64 * sizeof(int));
|
|
- FDKmemclear(sfbEnergyAct, 64 * sizeof(int));
|
|
-
|
|
- if (!frameOk || mute_release_active) {
|
|
- /* Restore last frame from concealment buffer */
|
|
- pIcsInfo->WindowShape = pConcealmentInfo->windowShape;
|
|
- pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;
|
|
-
|
|
- /* Restore spectral data */
|
|
- for (i = 0; i < samplesPerFrame; i++) {
|
|
- pSpectralCoefficient[i] =
|
|
- FX_CNCL2FX_DBL(pConcealmentInfo->spectralCoefficient[i]);
|
|
- }
|
|
-
|
|
- /* Restore scale factors */
|
|
- FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8 * sizeof(SHORT));
|
|
- }
|
|
-
|
|
- /* if previous frame was not ok */
|
|
- if (!pConcealmentInfo->prevFrameOk[1] || mute_release_active) {
|
|
- /* if current frame (f_n) is ok and the last but one frame (f_(n-2))
|
|
- was ok, too, then interpolate both frames in order to generate
|
|
- the current output frame (f_(n-1)). Otherwise, use the last stored
|
|
- frame (f_(n-2) or f_(n-3) or ...). */
|
|
- if (frameOk && pConcealmentInfo->prevFrameOk[0] && !mute_release_active) {
|
|
- appliedProcessing = 1;
|
|
-
|
|
- /* Interpolate both frames in order to generate the current output frame
|
|
- * (f_(n-1)). */
|
|
- if (pIcsInfo->WindowSequence == BLOCK_SHORT) {
|
|
- /* f_(n-2) == BLOCK_SHORT */
|
|
- /* short--??????--short, short--??????--long interpolation */
|
|
- /* short--short---short, short---long---long interpolation */
|
|
-
|
|
- int wnd;
|
|
-
|
|
- if (pConcealmentInfo->windowSequence ==
|
|
- BLOCK_SHORT) { /* f_n == BLOCK_SHORT */
|
|
- /* short--short---short interpolation */
|
|
-
|
|
- int scaleFactorBandsTotal =
|
|
- pSamplingRateInfo->NumberOfScaleFactorBands_Short;
|
|
- const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
|
|
- pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1;
|
|
- pIcsInfo->WindowSequence = BLOCK_SHORT;
|
|
-
|
|
- for (wnd = 0; wnd < 8; wnd++) {
|
|
- CConcealment_CalcBandEnergy(
|
|
- &pSpectralCoefficient[wnd *
|
|
- (samplesPerFrame / 8)], /* spec_(n-2) */
|
|
- pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand,
|
|
- sfbEnergyPrev);
|
|
-
|
|
- CConcealment_CalcBandEnergy(
|
|
- &pConcealmentInfo->spectralCoefficient[wnd * (samplesPerFrame /
|
|
- 8)], /* spec_n */
|
|
- pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand,
|
|
- sfbEnergyAct);
|
|
-
|
|
- CConcealment_InterpolateBuffer(
|
|
- &pSpectralCoefficient[wnd *
|
|
- (samplesPerFrame / 8)], /* spec_(n-1) */
|
|
- &pSpecScale[wnd], &pConcealmentInfo->specScale[wnd],
|
|
- &pSpecScale[wnd], sfbEnergyPrev, sfbEnergyAct,
|
|
- scaleFactorBandsTotal, pSfbOffset);
|
|
- }
|
|
- } else { /* f_n != BLOCK_SHORT */
|
|
- /* short---long---long interpolation */
|
|
-
|
|
- int scaleFactorBandsTotal =
|
|
- pSamplingRateInfo->NumberOfScaleFactorBands_Long;
|
|
- const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
|
|
- SHORT specScaleOut;
|
|
-
|
|
- CConcealment_CalcBandEnergy(
|
|
- &pSpectralCoefficient[samplesPerFrame -
|
|
- (samplesPerFrame /
|
|
- 8)], /* [wnd] spec_(n-2) */
|
|
- pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand,
|
|
- sfbEnergyAct);
|
|
-
|
|
- CConcealment_CalcBandEnergy(
|
|
- pConcealmentInfo->spectralCoefficient, /* spec_n */
|
|
- pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand,
|
|
- sfbEnergyPrev);
|
|
-
|
|
- pIcsInfo->WindowShape = 0;
|
|
- pIcsInfo->WindowSequence = BLOCK_STOP;
|
|
-
|
|
- for (i = 0; i < samplesPerFrame; i++) {
|
|
- pSpectralCoefficient[i] =
|
|
- pConcealmentInfo->spectralCoefficient[i]; /* spec_n */
|
|
- }
|
|
-
|
|
- for (i = 0; i < 8; i++) { /* search for max(specScale) */
|
|
- if (pSpecScale[i] > pSpecScale[0]) {
|
|
- pSpecScale[0] = pSpecScale[i];
|
|
- }
|
|
- }
|
|
-
|
|
- CConcealment_InterpolateBuffer(
|
|
- pSpectralCoefficient, /* spec_(n-1) */
|
|
- &pConcealmentInfo->specScale[0], &pSpecScale[0], &specScaleOut,
|
|
- sfbEnergyPrev, sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset);
|
|
-
|
|
- pSpecScale[0] = specScaleOut;
|
|
- }
|
|
- } else {
|
|
- /* long--??????--short, long--??????--long interpolation */
|
|
- /* long---long---short, long---long---long interpolation */
|
|
-
|
|
- int scaleFactorBandsTotal =
|
|
- pSamplingRateInfo->NumberOfScaleFactorBands_Long;
|
|
- const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
|
|
- SHORT specScaleAct = pConcealmentInfo->specScale[0];
|
|
-
|
|
- CConcealment_CalcBandEnergy(pSpectralCoefficient, /* spec_(n-2) */
|
|
- pSamplingRateInfo, BLOCK_LONG,
|
|
- CConcealment_NoExpand, sfbEnergyPrev);
|
|
-
|
|
- if (pConcealmentInfo->windowSequence ==
|
|
- BLOCK_SHORT) { /* f_n == BLOCK_SHORT */
|
|
- /* long---long---short interpolation */
|
|
-
|
|
- pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1;
|
|
- pIcsInfo->WindowSequence = BLOCK_START;
|
|
-
|
|
- for (i = 1; i < 8; i++) { /* search for max(specScale) */
|
|
- if (pConcealmentInfo->specScale[i] > specScaleAct) {
|
|
- specScaleAct = pConcealmentInfo->specScale[i];
|
|
- }
|
|
- }
|
|
-
|
|
- /* Expand first short spectrum */
|
|
- CConcealment_CalcBandEnergy(
|
|
- pConcealmentInfo->spectralCoefficient, /* spec_n */
|
|
- pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand, /* !!! */
|
|
- sfbEnergyAct);
|
|
- } else {
|
|
- /* long---long---long interpolation */
|
|
-
|
|
- pIcsInfo->WindowShape = 0;
|
|
- pIcsInfo->WindowSequence = BLOCK_LONG;
|
|
-
|
|
- CConcealment_CalcBandEnergy(
|
|
- pConcealmentInfo->spectralCoefficient, /* spec_n */
|
|
- pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand,
|
|
- sfbEnergyAct);
|
|
- }
|
|
-
|
|
- CConcealment_InterpolateBuffer(
|
|
- pSpectralCoefficient, /* spec_(n-1) */
|
|
- &pSpecScale[0], &specScaleAct, &pSpecScale[0], sfbEnergyPrev,
|
|
- sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset);
|
|
- }
|
|
- }
|
|
-
|
|
- /* Noise substitution of sign of the output spectral coefficients */
|
|
- CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase,
|
|
- pSpectralCoefficient, samplesPerFrame);
|
|
- /* Increment random phase index to avoid repetition artifacts. */
|
|
- pConcealmentInfo->iRandomPhase =
|
|
- (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
|
|
- }
|
|
-
|
|
- /* scale spectrum according to concealment state */
|
|
- switch (pConcealmentInfo->concealState) {
|
|
- case ConcealState_Single:
|
|
- appliedProcessing = 1;
|
|
- break;
|
|
-
|
|
- case ConcealState_FadeOut: {
|
|
- FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
|
|
- FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
|
|
- CONCEAL_MAX_NUM_FADE_FACTORS);
|
|
- FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
|
|
- pConcealCommonData->numFadeOutFrames);
|
|
-
|
|
- /* TimeDomainFading: */
|
|
- /* Attenuation of signal is done in CConcealment_TDFading() */
|
|
-
|
|
- appliedProcessing = 1;
|
|
- } break;
|
|
-
|
|
- case ConcealState_FadeIn: {
|
|
- FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
|
|
- FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
|
|
- CONCEAL_MAX_NUM_FADE_FACTORS);
|
|
- FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
|
|
- pConcealCommonData->numFadeInFrames);
|
|
-
|
|
- /* TimeDomainFading: */
|
|
- /* Attenuation of signal is done in CConcealment_TDFading() */
|
|
-
|
|
- appliedProcessing = 1;
|
|
- } break;
|
|
-
|
|
- case ConcealState_Mute: {
|
|
- /* set dummy window parameters */
|
|
- pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */
|
|
- pIcsInfo->WindowShape =
|
|
- pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape
|
|
- (required for F/T transform) */
|
|
- pIcsInfo->WindowSequence =
|
|
- CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
|
|
- pConcealmentInfo->windowSequence =
|
|
- pIcsInfo->WindowSequence; /* Store for next frame
|
|
- (spectrum in concealment
|
|
- buffer can't be used at
|
|
- all) */
|
|
-
|
|
- /* mute spectral data */
|
|
- FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
|
|
-
|
|
- appliedProcessing = 1;
|
|
- } break;
|
|
-
|
|
- default:
|
|
- /* nothing to do here */
|
|
- break;
|
|
- }
|
|
-
|
|
- return appliedProcessing;
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Calculate the spectral energy
|
|
-
|
|
- The function calculates band-wise the spectral energy. This is used for
|
|
- frame interpolation.
|
|
-*/
|
|
-static void CConcealment_CalcBandEnergy(
|
|
- FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo,
|
|
- const int blockType, CConcealmentExpandType expandType, int *sfbEnergy) {
|
|
- const SHORT *pSfbOffset;
|
|
- int line, sfb, scaleFactorBandsTotal = 0;
|
|
-
|
|
- /* In the following calculations, enAccu is initialized with LSB-value in
|
|
- * order to avoid zero energy-level */
|
|
-
|
|
- line = 0;
|
|
-
|
|
- switch (blockType) {
|
|
- case BLOCK_LONG:
|
|
- case BLOCK_START:
|
|
- case BLOCK_STOP:
|
|
-
|
|
- if (expandType == CConcealment_NoExpand) {
|
|
- /* standard long calculation */
|
|
- scaleFactorBandsTotal =
|
|
- pSamplingRateInfo->NumberOfScaleFactorBands_Long;
|
|
- pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
|
|
-
|
|
- for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
|
|
- FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
|
|
- int sfbScale =
|
|
- (sizeof(LONG) << 3) -
|
|
- CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
|
|
- /* scaling depends on sfb width. */
|
|
- for (; line < pSfbOffset[sfb + 1]; line++) {
|
|
- enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
|
|
- }
|
|
- *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
|
|
- }
|
|
- } else {
|
|
- /* compress long to short */
|
|
- scaleFactorBandsTotal =
|
|
- pSamplingRateInfo->NumberOfScaleFactorBands_Short;
|
|
- pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
|
|
-
|
|
- for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
|
|
- FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
|
|
- int sfbScale =
|
|
- (sizeof(LONG) << 3) -
|
|
- CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
|
|
- /* scaling depends on sfb width. */
|
|
- for (; line < pSfbOffset[sfb + 1] << 3; line++) {
|
|
- enAccu +=
|
|
- (enAccu + (fPow2Div2(*(spectrum + line)) >> sfbScale)) >> 3;
|
|
- }
|
|
- *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
|
|
- }
|
|
- }
|
|
- break;
|
|
-
|
|
- case BLOCK_SHORT:
|
|
-
|
|
- if (expandType == CConcealment_NoExpand) {
|
|
- /* standard short calculation */
|
|
- scaleFactorBandsTotal =
|
|
- pSamplingRateInfo->NumberOfScaleFactorBands_Short;
|
|
- pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
|
|
-
|
|
- for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
|
|
- FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
|
|
- int sfbScale =
|
|
- (sizeof(LONG) << 3) -
|
|
- CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
|
|
- /* scaling depends on sfb width. */
|
|
- for (; line < pSfbOffset[sfb + 1]; line++) {
|
|
- enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
|
|
- }
|
|
- *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
|
|
- }
|
|
- } else {
|
|
- /* expand short to long spectrum */
|
|
- scaleFactorBandsTotal =
|
|
- pSamplingRateInfo->NumberOfScaleFactorBands_Long;
|
|
- pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
|
|
-
|
|
- for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
|
|
- FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
|
|
- int sfbScale =
|
|
- (sizeof(LONG) << 3) -
|
|
- CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
|
|
- /* scaling depends on sfb width. */
|
|
- for (; line < pSfbOffset[sfb + 1]; line++) {
|
|
- enAccu += fPow2Div2(*(spectrum + (line >> 3))) >> sfbScale;
|
|
- }
|
|
- *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
|
|
- }
|
|
- }
|
|
- break;
|
|
- }
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Interpolate buffer
|
|
-
|
|
- The function creates the interpolated spectral data according to the
|
|
- energy of the last good frame and the current (good) frame.
|
|
-*/
|
|
-static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
|
|
- SHORT *pSpecScalePrv,
|
|
- SHORT *pSpecScaleAct,
|
|
- SHORT *pSpecScaleOut, int *enPrv,
|
|
- int *enAct, int sfbCnt,
|
|
- const SHORT *pSfbOffset) {
|
|
- int sfb, line = 0;
|
|
- int fac_shift;
|
|
- int fac_mod;
|
|
- FIXP_DBL accu;
|
|
-
|
|
- for (sfb = 0; sfb < sfbCnt; sfb++) {
|
|
- fac_shift =
|
|
- enPrv[sfb] - enAct[sfb] + ((*pSpecScaleAct - *pSpecScalePrv) << 1);
|
|
- fac_mod = fac_shift & 3;
|
|
- fac_shift = (fac_shift >> 2) + 1;
|
|
- fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct);
|
|
-
|
|
- 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;
|
|
- }
|
|
- }
|
|
- *pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct);
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Find next fading frame in case of changing fading direction
|
|
-
|
|
- \param pConcealCommonData Pointer to the concealment common data structure.
|
|
- \param actFadeIndex Last index used for fading
|
|
- \param direction Direction of change: 0 : change from FADE-OUT to FADE-IN, 1
|
|
- : change from FADE-IN to FADE-OUT
|
|
-
|
|
- This function determines the next fading index to be used for the fading
|
|
- direction to be changed to.
|
|
-*/
|
|
-
|
|
-static INT findEquiFadeFrame(CConcealParams *pConcealCommonData,
|
|
- INT actFadeIndex, int direction) {
|
|
- FIXP_SGL *pFactor;
|
|
- FIXP_SGL referenceVal;
|
|
- FIXP_SGL minDiff = (FIXP_SGL)MAXVAL_SGL;
|
|
-
|
|
- INT nextFadeIndex = 0;
|
|
-
|
|
- int i;
|
|
-
|
|
- /* init depending on direction */
|
|
- if (direction == 0) { /* FADE-OUT => FADE-IN */
|
|
- if (actFadeIndex < 0) {
|
|
- referenceVal = (FIXP_SGL)MAXVAL_SGL;
|
|
- } else {
|
|
- referenceVal = pConcealCommonData->fadeOutFactor[actFadeIndex] >> 1;
|
|
- }
|
|
- pFactor = pConcealCommonData->fadeInFactor;
|
|
- } else { /* FADE-IN => FADE-OUT */
|
|
- if (actFadeIndex < 0) {
|
|
- referenceVal = (FIXP_SGL)MAXVAL_SGL;
|
|
- } else {
|
|
- referenceVal = pConcealCommonData->fadeInFactor[actFadeIndex] >> 1;
|
|
- }
|
|
- pFactor = pConcealCommonData->fadeOutFactor;
|
|
- }
|
|
-
|
|
- /* search for minimum difference */
|
|
- for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
|
|
- FIXP_SGL diff = fixp_abs((pFactor[i] >> 1) - referenceVal);
|
|
- if (diff < minDiff) {
|
|
- minDiff = diff;
|
|
- nextFadeIndex = i;
|
|
- }
|
|
- }
|
|
-
|
|
- /* check and adjust depending on direction */
|
|
- if (direction == 0) { /* FADE-OUT => FADE-IN */
|
|
- if (nextFadeIndex > pConcealCommonData->numFadeInFrames) {
|
|
- nextFadeIndex = fMax(pConcealCommonData->numFadeInFrames - 1, 0);
|
|
- }
|
|
- if (((pFactor[nextFadeIndex] >> 1) <= referenceVal) &&
|
|
- (nextFadeIndex > 0)) {
|
|
- nextFadeIndex -= 1;
|
|
- }
|
|
- } else { /* FADE-IN => FADE-OUT */
|
|
- if (((pFactor[nextFadeIndex] >> 1) >= referenceVal) &&
|
|
- (nextFadeIndex < CONCEAL_MAX_NUM_FADE_FACTORS - 1)) {
|
|
- nextFadeIndex += 1;
|
|
- }
|
|
- }
|
|
-
|
|
- return (nextFadeIndex);
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Update the concealment state
|
|
-
|
|
- The function updates the state of the concealment state-machine. The
|
|
- states are: mute, fade-in, fade-out, interpolate and frame-ok.
|
|
-*/
|
|
-static void CConcealment_UpdateState(
|
|
- CConcealmentInfo *pConcealmentInfo, int frameOk,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
|
- const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
|
|
- CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
|
|
-
|
|
- switch (pConcealCommonData->method) {
|
|
- case ConcealMethodNoise: {
|
|
- if (pConcealmentInfo->concealState != ConcealState_Ok) {
|
|
- /* count the valid frames during concealment process */
|
|
- if (frameOk) {
|
|
- pConcealmentInfo->cntValidFrames += 1;
|
|
- } else {
|
|
- pConcealmentInfo->cntValidFrames = 0;
|
|
- }
|
|
- }
|
|
-
|
|
- /* -- STATE MACHINE for Noise Substitution -- */
|
|
- switch (pConcealmentInfo->concealState) {
|
|
- case ConcealState_Ok:
|
|
- if (!frameOk) {
|
|
- pConcealmentInfo->cntFadeFrames = 0;
|
|
- pConcealmentInfo->cntValidFrames = 0;
|
|
- pConcealmentInfo->attGrpOffset[0] = 0;
|
|
- pConcealmentInfo->attGrpOffset[1] = 0;
|
|
- pConcealmentInfo->winGrpOffset[0] = 0;
|
|
- pConcealmentInfo->winGrpOffset[1] = 0;
|
|
- if (pConcealCommonData->numFadeOutFrames > 0) {
|
|
- /* change to state SINGLE-FRAME-LOSS */
|
|
- pConcealmentInfo->concealState = ConcealState_Single;
|
|
- /* mode 0 just updates the Fading counter */
|
|
- CConcealment_ApplyFadeOut(
|
|
- /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
|
|
- samplesPerFrame, pAacDecoderChannelInfo);
|
|
-
|
|
- } else {
|
|
- /* change to state MUTE */
|
|
- pConcealmentInfo->concealState = ConcealState_Mute;
|
|
- }
|
|
- }
|
|
- break;
|
|
-
|
|
- case ConcealState_Single: /* Just a pre-stage before fade-out begins.
|
|
- Stay here only one frame! */
|
|
- if (frameOk) {
|
|
- /* change to state OK */
|
|
- pConcealmentInfo->concealState = ConcealState_Ok;
|
|
- } else {
|
|
- if (pConcealmentInfo->cntFadeFrames >=
|
|
- pConcealCommonData->numFadeOutFrames) {
|
|
- /* change to state MUTE */
|
|
- pConcealmentInfo->concealState = ConcealState_Mute;
|
|
- } else {
|
|
- /* change to state FADE-OUT */
|
|
- pConcealmentInfo->concealState = ConcealState_FadeOut;
|
|
- /* mode 0 just updates the Fading counter */
|
|
- CConcealment_ApplyFadeOut(
|
|
- /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
|
|
- samplesPerFrame, pAacDecoderChannelInfo);
|
|
- }
|
|
- }
|
|
- break;
|
|
-
|
|
- case ConcealState_FadeOut:
|
|
- if (pConcealmentInfo->cntValidFrames >
|
|
- pConcealCommonData->numMuteReleaseFrames) {
|
|
- if (pConcealCommonData->numFadeInFrames > 0) {
|
|
- /* change to state FADE-IN */
|
|
- pConcealmentInfo->concealState = ConcealState_FadeIn;
|
|
- pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
|
|
- pConcealCommonData, pConcealmentInfo->cntFadeFrames,
|
|
- 0 /* FadeOut -> FadeIn */);
|
|
- } else {
|
|
- /* change to state OK */
|
|
- pConcealmentInfo->concealState = ConcealState_Ok;
|
|
- }
|
|
- } else {
|
|
- if (frameOk) {
|
|
- /* we have good frame information but stay fully in concealment -
|
|
- * reset winGrpOffset/attGrpOffset */
|
|
- pConcealmentInfo->winGrpOffset[0] = 0;
|
|
- pConcealmentInfo->winGrpOffset[1] = 0;
|
|
- pConcealmentInfo->attGrpOffset[0] = 0;
|
|
- pConcealmentInfo->attGrpOffset[1] = 0;
|
|
- }
|
|
- if (pConcealmentInfo->cntFadeFrames >=
|
|
- pConcealCommonData->numFadeOutFrames) {
|
|
- /* change to state MUTE */
|
|
- pConcealmentInfo->concealState = ConcealState_Mute;
|
|
- } else /* Stay in FADE-OUT */
|
|
- {
|
|
- /* mode 0 just updates the Fading counter */
|
|
- CConcealment_ApplyFadeOut(
|
|
- /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
|
|
- samplesPerFrame, pAacDecoderChannelInfo);
|
|
- }
|
|
- }
|
|
- break;
|
|
-
|
|
- case ConcealState_Mute:
|
|
- if (pConcealmentInfo->cntValidFrames >
|
|
- pConcealCommonData->numMuteReleaseFrames) {
|
|
- if (pConcealCommonData->numFadeInFrames > 0) {
|
|
- /* change to state FADE-IN */
|
|
- pConcealmentInfo->concealState = ConcealState_FadeIn;
|
|
- pConcealmentInfo->cntFadeFrames =
|
|
- pConcealCommonData->numFadeInFrames - 1;
|
|
- } else {
|
|
- /* change to state OK */
|
|
- pConcealmentInfo->concealState = ConcealState_Ok;
|
|
- }
|
|
- } else {
|
|
- if (frameOk) {
|
|
- /* we have good frame information but stay fully in concealment -
|
|
- * reset winGrpOffset/attGrpOffset */
|
|
- pConcealmentInfo->winGrpOffset[0] = 0;
|
|
- pConcealmentInfo->winGrpOffset[1] = 0;
|
|
- pConcealmentInfo->attGrpOffset[0] = 0;
|
|
- pConcealmentInfo->attGrpOffset[1] = 0;
|
|
- }
|
|
- }
|
|
- break;
|
|
-
|
|
- case ConcealState_FadeIn:
|
|
- pConcealmentInfo->cntFadeFrames -= 1;
|
|
- if (frameOk) {
|
|
- if (pConcealmentInfo->cntFadeFrames < 0) {
|
|
- /* change to state OK */
|
|
- pConcealmentInfo->concealState = ConcealState_Ok;
|
|
- }
|
|
- } else {
|
|
- if (pConcealCommonData->numFadeOutFrames > 0) {
|
|
- /* change to state FADE-OUT */
|
|
- pConcealmentInfo->concealState = ConcealState_FadeOut;
|
|
- pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
|
|
- pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1,
|
|
- 1 /* FadeIn -> FadeOut */);
|
|
- pConcealmentInfo->winGrpOffset[0] = 0;
|
|
- pConcealmentInfo->winGrpOffset[1] = 0;
|
|
- pConcealmentInfo->attGrpOffset[0] = 0;
|
|
- pConcealmentInfo->attGrpOffset[1] = 0;
|
|
-
|
|
- pConcealmentInfo
|
|
- ->cntFadeFrames--; /* decrease because
|
|
- CConcealment_ApplyFadeOut() will
|
|
- increase, accordingly */
|
|
- /* mode 0 just updates the Fading counter */
|
|
- CConcealment_ApplyFadeOut(
|
|
- /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
|
|
- samplesPerFrame, pAacDecoderChannelInfo);
|
|
- } else {
|
|
- /* change to state MUTE */
|
|
- pConcealmentInfo->concealState = ConcealState_Mute;
|
|
- }
|
|
- }
|
|
- break;
|
|
-
|
|
- default:
|
|
- FDK_ASSERT(0);
|
|
- break;
|
|
- }
|
|
- } break;
|
|
-
|
|
- case ConcealMethodInter:
|
|
- case ConcealMethodTonal: {
|
|
- if (pConcealmentInfo->concealState != ConcealState_Ok) {
|
|
- /* count the valid frames during concealment process */
|
|
- if (pConcealmentInfo->prevFrameOk[1] ||
|
|
- (pConcealmentInfo->prevFrameOk[0] &&
|
|
- !pConcealmentInfo->prevFrameOk[1] && frameOk)) {
|
|
- /* The frame is OK even if it can be estimated by the energy
|
|
- * interpolation algorithm */
|
|
- pConcealmentInfo->cntValidFrames += 1;
|
|
- } else {
|
|
- pConcealmentInfo->cntValidFrames = 0;
|
|
- }
|
|
- }
|
|
-
|
|
- /* -- STATE MACHINE for energy interpolation -- */
|
|
- switch (pConcealmentInfo->concealState) {
|
|
- case ConcealState_Ok:
|
|
- if (!(pConcealmentInfo->prevFrameOk[1] ||
|
|
- (pConcealmentInfo->prevFrameOk[0] &&
|
|
- !pConcealmentInfo->prevFrameOk[1] && frameOk))) {
|
|
- if (pConcealCommonData->numFadeOutFrames > 0) {
|
|
- /* Fade out only if the energy interpolation algorithm can not be
|
|
- * applied! */
|
|
- pConcealmentInfo->concealState = ConcealState_FadeOut;
|
|
- } else {
|
|
- /* change to state MUTE */
|
|
- pConcealmentInfo->concealState = ConcealState_Mute;
|
|
- }
|
|
- pConcealmentInfo->cntFadeFrames = 0;
|
|
- pConcealmentInfo->cntValidFrames = 0;
|
|
- }
|
|
- break;
|
|
-
|
|
- case ConcealState_Single:
|
|
- pConcealmentInfo->concealState = ConcealState_Ok;
|
|
- break;
|
|
-
|
|
- case ConcealState_FadeOut:
|
|
- pConcealmentInfo->cntFadeFrames += 1;
|
|
-
|
|
- if (pConcealmentInfo->cntValidFrames >
|
|
- pConcealCommonData->numMuteReleaseFrames) {
|
|
- if (pConcealCommonData->numFadeInFrames > 0) {
|
|
- /* change to state FADE-IN */
|
|
- pConcealmentInfo->concealState = ConcealState_FadeIn;
|
|
- pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
|
|
- pConcealCommonData, pConcealmentInfo->cntFadeFrames - 1,
|
|
- 0 /* FadeOut -> FadeIn */);
|
|
- } else {
|
|
- /* change to state OK */
|
|
- pConcealmentInfo->concealState = ConcealState_Ok;
|
|
- }
|
|
- } else {
|
|
- if (pConcealmentInfo->cntFadeFrames >=
|
|
- pConcealCommonData->numFadeOutFrames) {
|
|
- /* change to state MUTE */
|
|
- pConcealmentInfo->concealState = ConcealState_Mute;
|
|
- }
|
|
- }
|
|
- break;
|
|
-
|
|
- case ConcealState_Mute:
|
|
- if (pConcealmentInfo->cntValidFrames >
|
|
- pConcealCommonData->numMuteReleaseFrames) {
|
|
- if (pConcealCommonData->numFadeInFrames > 0) {
|
|
- /* change to state FADE-IN */
|
|
- pConcealmentInfo->concealState = ConcealState_FadeIn;
|
|
- pConcealmentInfo->cntFadeFrames =
|
|
- pConcealCommonData->numFadeInFrames - 1;
|
|
- } else {
|
|
- /* change to state OK */
|
|
- pConcealmentInfo->concealState = ConcealState_Ok;
|
|
- }
|
|
- }
|
|
- break;
|
|
-
|
|
- case ConcealState_FadeIn:
|
|
- pConcealmentInfo->cntFadeFrames -=
|
|
- 1; /* used to address the fade-in factors */
|
|
-
|
|
- if (frameOk || pConcealmentInfo->prevFrameOk[1]) {
|
|
- if (pConcealmentInfo->cntFadeFrames < 0) {
|
|
- /* change to state OK */
|
|
- pConcealmentInfo->concealState = ConcealState_Ok;
|
|
- }
|
|
- } else {
|
|
- if (pConcealCommonData->numFadeOutFrames > 0) {
|
|
- /* change to state FADE-OUT */
|
|
- pConcealmentInfo->concealState = ConcealState_FadeOut;
|
|
- pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
|
|
- pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1,
|
|
- 1 /* FadeIn -> FadeOut */);
|
|
- } else {
|
|
- /* change to state MUTE */
|
|
- pConcealmentInfo->concealState = ConcealState_Mute;
|
|
- }
|
|
- }
|
|
- break;
|
|
- } /* End switch(pConcealmentInfo->concealState) */
|
|
- } break;
|
|
-
|
|
- default:
|
|
- /* Don't need a state machine for other concealment methods. */
|
|
- break;
|
|
- }
|
|
-}
|
|
-
|
|
-/*!
|
|
-\brief Randomizes the sign of the spectral data
|
|
-
|
|
- The function toggles the sign of the spectral data randomly. This is
|
|
- useful to ensure the quality of the concealed frames.
|
|
- */
|
|
-static void CConcealment_ApplyRandomSign(int randomPhase, FIXP_DBL *spec,
|
|
- int samplesPerFrame) {
|
|
- int i;
|
|
- USHORT packedSign = 0;
|
|
-
|
|
- /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit
|
|
- */
|
|
-
|
|
- /* read current packed sign word */
|
|
- packedSign = AacDec_randomSign[randomPhase >> 4];
|
|
- packedSign >>= (randomPhase & 0xf);
|
|
-
|
|
- for (i = 0; i < samplesPerFrame; i++) {
|
|
- if ((randomPhase & 0xf) == 0) {
|
|
- packedSign = AacDec_randomSign[randomPhase >> 4];
|
|
- }
|
|
-
|
|
- if (packedSign & 0x1) {
|
|
- spec[i] = -spec[i];
|
|
- }
|
|
- packedSign >>= 1;
|
|
-
|
|
- randomPhase = (randomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
|
|
- }
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Get fadeing factor for current concealment state.
|
|
-
|
|
- The function returns the state (ok or not) of the previous frame.
|
|
- If called before the function CConcealment_Apply() set the fBeforeApply
|
|
- flag to get the correct value.
|
|
-
|
|
- \return Frame OK flag of previous frame.
|
|
- */
|
|
-int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo,
|
|
- const int fBeforeApply) {
|
|
- int prevFrameOk = 1;
|
|
-
|
|
- if (hConcealmentInfo != NULL) {
|
|
- prevFrameOk = hConcealmentInfo->prevFrameOk[fBeforeApply & 0x1];
|
|
- }
|
|
-
|
|
- return prevFrameOk;
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Get the number of delay frames introduced by concealment technique.
|
|
-
|
|
- \return Number of delay frames.
|
|
- */
|
|
-UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData) {
|
|
- UINT frameDelay = 0;
|
|
-
|
|
- if (pConcealCommonData != NULL) {
|
|
- switch (pConcealCommonData->method) {
|
|
- case ConcealMethodTonal:
|
|
- case ConcealMethodInter:
|
|
- frameDelay = 1;
|
|
- break;
|
|
- default:
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- return frameDelay;
|
|
-}
|
|
-
|
|
-static int CConcealment_ApplyFadeOut(
|
|
- int mode, CConcealmentInfo *pConcealmentInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
|
- const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
|
|
- /* mode 1 = apply RandomSign and mute spectral coefficients if necessary, *
|
|
- * mode 0 = Update cntFadeFrames */
|
|
-
|
|
- /* restore frequency coefficients from buffer with a specific muting */
|
|
- int srcWin, dstWin, numWindows = 1;
|
|
- int windowLen = samplesPerFrame;
|
|
- int srcGrpStart = 0;
|
|
- int winIdxStride = 1;
|
|
- int numWinGrpPerFac, attIdx, attIdxStride;
|
|
- int i;
|
|
- int appliedProcessing = 0;
|
|
-
|
|
- CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
|
|
- FIXP_DBL *pSpectralCoefficient =
|
|
- SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
|
|
- SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
|
|
-
|
|
- /* set old window parameters */
|
|
- if (pConcealmentInfo->lastRenderMode == AACDEC_RENDER_LPD) {
|
|
- switch (pAacDecoderStaticChannelInfo->last_lpd_mode) {
|
|
- case 1:
|
|
- numWindows = 4;
|
|
- srcGrpStart = 3;
|
|
- windowLen = samplesPerFrame >> 2;
|
|
- break;
|
|
- case 2:
|
|
- numWindows = 2;
|
|
- srcGrpStart = 1;
|
|
- windowLen = samplesPerFrame >> 1;
|
|
- winIdxStride = 2;
|
|
- break;
|
|
- case 3:
|
|
- numWindows = 1;
|
|
- srcGrpStart = 0;
|
|
- windowLen = samplesPerFrame;
|
|
- winIdxStride = 4;
|
|
- break;
|
|
- }
|
|
- pConcealmentInfo->lastWinGrpLen = 1;
|
|
- } else {
|
|
- pIcsInfo->WindowShape = pConcealmentInfo->windowShape;
|
|
- pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;
|
|
-
|
|
- if (pConcealmentInfo->windowSequence == BLOCK_SHORT) {
|
|
- /* short block handling */
|
|
- numWindows = 8;
|
|
- windowLen = samplesPerFrame >> 3;
|
|
- srcGrpStart = numWindows - pConcealmentInfo->lastWinGrpLen;
|
|
- }
|
|
- }
|
|
-
|
|
- attIdxStride =
|
|
- fMax(1, (int)(numWindows / (pConcealmentInfo->lastWinGrpLen + 1)));
|
|
-
|
|
- /* load last state */
|
|
- attIdx = pConcealmentInfo->cntFadeFrames;
|
|
- numWinGrpPerFac = pConcealmentInfo->attGrpOffset[mode];
|
|
- srcWin = srcGrpStart + pConcealmentInfo->winGrpOffset[mode];
|
|
-
|
|
- FDK_ASSERT((srcGrpStart * windowLen + windowLen) <= samplesPerFrame);
|
|
- FDK_ASSERT((srcWin * windowLen + windowLen) <= 1024);
|
|
-
|
|
- for (dstWin = 0; dstWin < numWindows; dstWin += 1) {
|
|
- FIXP_CNCL *pCncl =
|
|
- pConcealmentInfo->spectralCoefficient + (srcWin * windowLen);
|
|
- FIXP_DBL *pOut = pSpectralCoefficient + (dstWin * windowLen);
|
|
-
|
|
- if (mode == 1) {
|
|
- /* mute if attIdx gets large enaugh */
|
|
- if (attIdx > pConcealmentInfo->pConcealParams->numFadeOutFrames) {
|
|
- FDKmemclear(pCncl, sizeof(FIXP_DBL) * windowLen);
|
|
- }
|
|
-
|
|
- /* restore frequency coefficients from buffer - attenuation is done later
|
|
- */
|
|
- for (i = 0; i < windowLen; i++) {
|
|
- pOut[i] = pCncl[i];
|
|
- }
|
|
-
|
|
- /* apply random change of sign for spectral coefficients */
|
|
- CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase, pOut,
|
|
- windowLen);
|
|
-
|
|
- /* Increment random phase index to avoid repetition artifacts. */
|
|
- pConcealmentInfo->iRandomPhase =
|
|
- (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
|
|
-
|
|
- /* set old scale factors */
|
|
- pSpecScale[dstWin * winIdxStride] =
|
|
- pConcealmentInfo->specScale[srcWin * winIdxStride];
|
|
- }
|
|
-
|
|
- srcWin += 1;
|
|
-
|
|
- if (srcWin >= numWindows) {
|
|
- /* end of sequence -> rewind to first window of group */
|
|
- srcWin = srcGrpStart;
|
|
- numWinGrpPerFac += 1;
|
|
- if (numWinGrpPerFac >= attIdxStride) {
|
|
- numWinGrpPerFac = 0;
|
|
- attIdx += 1;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- /* store current state */
|
|
-
|
|
- pConcealmentInfo->winGrpOffset[mode] = srcWin - srcGrpStart;
|
|
- FDK_ASSERT((pConcealmentInfo->winGrpOffset[mode] >= 0) &&
|
|
- (pConcealmentInfo->winGrpOffset[mode] < 8));
|
|
- pConcealmentInfo->attGrpOffset[mode] = numWinGrpPerFac;
|
|
- FDK_ASSERT((pConcealmentInfo->attGrpOffset[mode] >= 0) &&
|
|
- (pConcealmentInfo->attGrpOffset[mode] < attIdxStride));
|
|
-
|
|
- if (mode == 0) {
|
|
- pConcealmentInfo->cntFadeFrames = attIdx;
|
|
- }
|
|
-
|
|
- appliedProcessing = 1;
|
|
-
|
|
- return appliedProcessing;
|
|
-}
|
|
-
|
|
-/*!
|
|
- \brief Do Time domain fading (TDFading) in concealment case
|
|
-
|
|
- In case of concealment, this function takes care of the fading, after time
|
|
-domain signal has been rendered by the respective signal rendering functions.
|
|
- The fading out in case of ACELP decoding is not done by this function but by
|
|
-the ACELP decoder for the first concealed frame if CONCEAL_CORE_IGNORANT_FADE is
|
|
-not set.
|
|
-
|
|
- TimeDomain fading never creates jumps in energy / discontinuities, it always
|
|
-does a continuous fading. To achieve this, fading is always done from a starting
|
|
-point to a target point, while the starting point is always determined to be the
|
|
-last target point. By varying the target point of a fading, the fading slope can
|
|
-be controlled.
|
|
-
|
|
- This principle is applied to the fading within a frame and the fading from
|
|
-frame to frame.
|
|
-
|
|
- One frame is divided into 8 subframes to obtain 8 parts of fading slopes
|
|
-within a frame, each maybe with its own gradient.
|
|
-
|
|
- Workflow:
|
|
- 1.) Determine Fading behavior and end-of-frame target fading level, based on
|
|
-concealmentState (determined by CConcealment_UpdateState()) and the core mode.
|
|
- - By _DEFAULT_,
|
|
- The target fading level is determined by fadeOutFactor[cntFadeFrames]
|
|
-in case of fadeOut, or fadeInFactor[cntFadeFrames] in case of fadeIn.
|
|
- --> fading type is FADE_TIMEDOMAIN in this case. Target fading level
|
|
-is determined by fading index cntFadeFrames.
|
|
-
|
|
- - If concealmentState is signalling a _MUTED SIGNAL_,
|
|
- TDFading decays to 0 within 1/8th of a frame if numFadeOutFrames == 0.
|
|
- --> fading type is FADE_TIMEDOMAIN_TOSPECTRALMUTE in this case.
|
|
-
|
|
- - If concealmentState is signalling the _END OF MUTING_,
|
|
- TDFading fades to target fading level within 1/8th of a frame if
|
|
-numFadeInFrames == 0.
|
|
- --> fading type is FADE_TIMEDOMAIN_FROMSPECTRALMUTE in this case.
|
|
-Target fading level is determined by fading index cntFadeFrames.
|
|
-
|
|
-#ifndef CONCEAL_CORE_IGNORANT_FADE
|
|
- - In case of an _ACELP FADEOUT_,
|
|
- TDFading leaves fading control to ACELP decoder for 1/2 frame.
|
|
- --> fading type is FADE_ACELPDOMAIN in this case.
|
|
-#endif
|
|
-
|
|
- 2.) Render fading levels within current frame and do the final fading:
|
|
- Map Fading slopes to fading levels and apply to time domain signal.
|
|
-
|
|
-
|
|
-*/
|
|
-
|
|
-INT CConcealment_TDFading(
|
|
- int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
|
|
- FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1) {
|
|
- /*
|
|
- Do the fading in Time domain based on concealment states and core mode
|
|
- */
|
|
- FIXP_DBL fadeStop, attMute = (FIXP_DBL)0;
|
|
- int idx = 0, ii;
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo =
|
|
- *ppAacDecoderStaticChannelInfo;
|
|
- CConcealmentInfo *pConcealmentInfo =
|
|
- &pAacDecoderStaticChannelInfo->concealmentInfo;
|
|
- CConcealParams *pConcealParams = pConcealmentInfo->pConcealParams;
|
|
- const CConcealmentState concealState = pConcealmentInfo->concealState;
|
|
- TDfadingType fadingType;
|
|
- FIXP_DBL fadingStations[9] = {0};
|
|
- int fadingSteps[8] = {0};
|
|
- const FIXP_DBL fadeStart =
|
|
- pConcealmentInfo
|
|
- ->fade_old; /* start fading at last end-of-frame attenuation */
|
|
- FIXP_SGL *fadeFactor = pConcealParams->fadeOutFactor;
|
|
- const INT cntFadeFrames = pConcealmentInfo->cntFadeFrames;
|
|
- int TDFadeOutStopBeforeMute = 1;
|
|
- int TDFadeInStopBeforeFullLevel = 1;
|
|
-
|
|
- /*
|
|
- determine Fading behaviour (end-of-frame attenuation and fading type) (1.)
|
|
- */
|
|
-
|
|
- switch (concealState) {
|
|
- case ConcealState_Single:
|
|
- case ConcealState_Mute:
|
|
- case ConcealState_FadeOut:
|
|
- idx = (pConcealParams->method == ConcealMethodNoise) ? cntFadeFrames - 1
|
|
- : cntFadeFrames;
|
|
- fadingType = FADE_TIMEDOMAIN;
|
|
-
|
|
- if (concealState == ConcealState_Mute ||
|
|
- (cntFadeFrames + TDFadeOutStopBeforeMute) >
|
|
- pConcealmentInfo->pConcealParams->numFadeOutFrames) {
|
|
- fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE;
|
|
- }
|
|
-
|
|
- break;
|
|
- case ConcealState_FadeIn:
|
|
- idx = cntFadeFrames;
|
|
- idx -= TDFadeInStopBeforeFullLevel;
|
|
- FDK_FALLTHROUGH;
|
|
- case ConcealState_Ok:
|
|
- fadeFactor = pConcealParams->fadeInFactor;
|
|
- idx = (concealState == ConcealState_Ok) ? -1 : idx;
|
|
- fadingType = (pConcealmentInfo->concealState_old == ConcealState_Mute)
|
|
- ? FADE_TIMEDOMAIN_FROMSPECTRALMUTE
|
|
- : FADE_TIMEDOMAIN;
|
|
- break;
|
|
- default:
|
|
- FDK_ASSERT(0);
|
|
- fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE;
|
|
- break;
|
|
- }
|
|
-
|
|
- /* determine Target end-of-frame fading level and fading slope */
|
|
- switch (fadingType) {
|
|
- case FADE_TIMEDOMAIN_FROMSPECTRALMUTE:
|
|
- fadeStop =
|
|
- (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]);
|
|
- if (pConcealmentInfo->pConcealParams->numFadeInFrames == 0) {
|
|
- /* do step as fast as possible */
|
|
- fadingSteps[0] = 1;
|
|
- break;
|
|
- }
|
|
- CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
|
|
- break;
|
|
- case FADE_TIMEDOMAIN:
|
|
- fadeStop =
|
|
- (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]);
|
|
- CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
|
|
- break;
|
|
- case FADE_TIMEDOMAIN_TOSPECTRALMUTE:
|
|
- fadeStop = attMute;
|
|
- if (pConcealmentInfo->pConcealParams->numFadeOutFrames == 0) {
|
|
- /* do step as fast as possible */
|
|
- fadingSteps[0] = 1;
|
|
- break;
|
|
- }
|
|
- CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
|
|
- break;
|
|
- }
|
|
-
|
|
- /*
|
|
- Render fading levels within current frame and do the final fading (2.)
|
|
- */
|
|
-
|
|
- len >>= 3;
|
|
- CConcealment_TDFadeFillFadingStations(fadingStations, fadingSteps, fadeStop,
|
|
- fadeStart, fadingType);
|
|
-
|
|
- if ((fadingStations[8] != (FIXP_DBL)MAXVAL_DBL) ||
|
|
- (fadingStations[7] != (FIXP_DBL)MAXVAL_DBL) ||
|
|
- (fadingStations[6] != (FIXP_DBL)MAXVAL_DBL) ||
|
|
- (fadingStations[5] != (FIXP_DBL)MAXVAL_DBL) ||
|
|
- (fadingStations[4] != (FIXP_DBL)MAXVAL_DBL) ||
|
|
- (fadingStations[3] != (FIXP_DBL)MAXVAL_DBL) ||
|
|
- (fadingStations[2] != (FIXP_DBL)MAXVAL_DBL) ||
|
|
- (fadingStations[1] != (FIXP_DBL)MAXVAL_DBL) ||
|
|
- (fadingStations[0] !=
|
|
- (FIXP_DBL)MAXVAL_DBL)) /* if there's something to fade */
|
|
- {
|
|
- int start = 0;
|
|
- for (ii = 0; ii < 8; ii++) {
|
|
- CConcealment_TDFadePcmAtt(start, len, fadingStations[ii],
|
|
- fadingStations[ii + 1], pcmdata);
|
|
- start += len;
|
|
- }
|
|
- }
|
|
- CConcealment_TDNoise_Apply(pConcealmentInfo, len, pcmdata);
|
|
-
|
|
- /* Save end-of-frame attenuation and fading type */
|
|
- pConcealmentInfo->lastFadingType = fadingType;
|
|
- pConcealmentInfo->fade_old = fadeStop;
|
|
- pConcealmentInfo->concealState_old = concealState;
|
|
-
|
|
- return 1;
|
|
-}
|
|
-
|
|
-/* attenuate pcmdata in Time Domain Fading process */
|
|
-static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
|
|
- FIXP_DBL fadeStop, FIXP_PCM *pcmdata) {
|
|
- int i;
|
|
- FIXP_DBL dStep;
|
|
- FIXP_DBL dGain;
|
|
- FIXP_DBL dGain_apply;
|
|
- int bitshift = (DFRACT_BITS - SAMPLE_BITS);
|
|
-
|
|
- /* set start energy */
|
|
- dGain = fadeStart;
|
|
- /* determine energy steps from sample to sample */
|
|
- dStep = (FIXP_DBL)((int)((fadeStart >> 1) - (fadeStop >> 1)) / len) << 1;
|
|
-
|
|
- for (i = start; i < (start + len); i++) {
|
|
- dGain -= dStep;
|
|
- /* prevent gain from getting negative due to possible fixpoint inaccuracies
|
|
- */
|
|
- dGain_apply = fMax((FIXP_DBL)0, dGain);
|
|
- /* finally, attenuate samples */
|
|
- pcmdata[i] = (FIXP_PCM)((fMult(pcmdata[i], (dGain_apply))) >> bitshift);
|
|
- }
|
|
-}
|
|
-
|
|
-/*
|
|
-\brief Fill FadingStations
|
|
-
|
|
-The fadingstations are the attenuation factors, being applied to its dedicated
|
|
-portions of pcm data. They are calculated using the fadingsteps. One fadingstep
|
|
-is the weighted contribution to the fading slope within its dedicated portion of
|
|
-pcm data.
|
|
-
|
|
-*Fadingsteps : 0 0 0 1 0 1 2 0
|
|
-
|
|
- |<- 1 Frame pcm data ->|
|
|
- fadeStart-->|__________ |
|
|
- ^ ^ ^ ^ \____ |
|
|
- Attenuation : | | | | ^ ^\__ |
|
|
- | | | | | | ^\ |
|
|
- | | | | | | | \___|<-- fadeStop
|
|
- | | | | | | | ^ ^
|
|
- | | | | | | | | |
|
|
-Fadingstations: [0][1][2][3][4][5][6][7][8]
|
|
-
|
|
-(Fadingstations "[0]" is "[8] from previous frame", therefore its not meaningful
|
|
-to be edited)
|
|
-
|
|
-*/
|
|
-static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
|
|
- int *fadingSteps,
|
|
- FIXP_DBL fadeStop,
|
|
- FIXP_DBL fadeStart,
|
|
- TDfadingType fadingType) {
|
|
- int i;
|
|
- INT fadingSteps_sum = 0;
|
|
- INT fadeDiff;
|
|
-
|
|
- fadingSteps_sum = fadingSteps[0] + fadingSteps[1] + fadingSteps[2] +
|
|
- fadingSteps[3] + fadingSteps[4] + fadingSteps[5] +
|
|
- fadingSteps[6] + fadingSteps[7];
|
|
- fadeDiff = ((INT)(fadeStop - fadeStart) / fMax(fadingSteps_sum, (INT)1));
|
|
- fadingStations[0] = fadeStart;
|
|
- for (i = 1; i < 8; i++) {
|
|
- fadingStations[i] =
|
|
- fadingStations[i - 1] + (FIXP_DBL)(fadeDiff * fadingSteps[i - 1]);
|
|
- }
|
|
- fadingStations[8] = fadeStop;
|
|
-}
|
|
-
|
|
-static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps) {
|
|
- fadingSteps[0] = fadingSteps[1] = fadingSteps[2] = fadingSteps[3] =
|
|
- fadingSteps[4] = fadingSteps[5] = fadingSteps[6] = fadingSteps[7] = 1;
|
|
-}
|
|
-
|
|
-/* end of TimeDomainFading functions */
|
|
-
|
|
-/* derived from int UsacRandomSign() */
|
|
-static int CConcealment_TDNoise_Random(ULONG *seed) {
|
|
- *seed = (ULONG)(((UINT64)(*seed) * 69069) + 5);
|
|
- return (int)(*seed);
|
|
-}
|
|
-
|
|
-static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
|
|
- const int len, FIXP_PCM *const pcmdata) {
|
|
- FIXP_PCM *states = pConcealmentInfo->TDNoiseStates;
|
|
- FIXP_PCM noiseVal;
|
|
- FIXP_DBL noiseValLong;
|
|
- FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef;
|
|
- FIXP_DBL TDNoiseAtt;
|
|
- ULONG seed = pConcealmentInfo->TDNoiseSeed =
|
|
- (ULONG)CConcealment_TDNoise_Random(&pConcealmentInfo->TDNoiseSeed) + 1;
|
|
-
|
|
- TDNoiseAtt = pConcealmentInfo->pConcealParams->comfortNoiseLevel;
|
|
-
|
|
- int ii;
|
|
-
|
|
- if ((pConcealmentInfo->concealState != ConcealState_Ok ||
|
|
- pConcealmentInfo->concealState_old != ConcealState_Ok) &&
|
|
- TDNoiseAtt != (FIXP_DBL)0) {
|
|
- for (ii = 0; ii < (len << 3); ii++) {
|
|
- /* create filtered noise */
|
|
- states[2] = states[1];
|
|
- states[1] = states[0];
|
|
- states[0] = ((FIXP_PCM)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));
|
|
-
|
|
- /* 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;
|
|
- }
|
|
-
|
|
- pcmdata[ii] += noiseVal;
|
|
- }
|
|
- }
|
|
-}
|
|
--- a/libAACdec/src/conceal.h
|
|
+++ /dev/null
|
|
@@ -1,152 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s): Josef Hoepfl
|
|
-
|
|
- Description: independent channel concealment
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-#ifndef CONCEAL_H
|
|
-#define CONCEAL_H
|
|
-
|
|
-#include "channelinfo.h"
|
|
-
|
|
-#define AACDEC_CONCEAL_PARAM_NOT_SPECIFIED (0xFFFE)
|
|
-
|
|
-void CConcealment_InitCommonData(CConcealParams *pConcealCommonData);
|
|
-
|
|
-void CConcealment_InitChannelData(CConcealmentInfo *hConcealmentInfo,
|
|
- CConcealParams *pConcealCommonData,
|
|
- AACDEC_RENDER_MODE initRenderMode,
|
|
- int samplesPerFrame);
|
|
-
|
|
-CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData);
|
|
-
|
|
-UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData);
|
|
-
|
|
-AAC_DECODER_ERROR
|
|
-CConcealment_SetParams(CConcealParams *concealParams, int method,
|
|
- int fadeOutSlope, int fadeInSlope, int muteRelease,
|
|
- FIXP_DBL comfNoiseLevel);
|
|
-
|
|
-CConcealmentState CConcealment_GetState(CConcealmentInfo *hConcealmentInfo);
|
|
-
|
|
-AAC_DECODER_ERROR
|
|
-CConcealment_SetAttenuation(CConcealParams *concealParams,
|
|
- const SHORT *fadeOutAttenuationVector,
|
|
- const SHORT *fadeInAttenuationVector);
|
|
-
|
|
-void CConcealment_Store(
|
|
- CConcealmentInfo *hConcealmentInfo,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo);
|
|
-
|
|
-int CConcealment_Apply(
|
|
- CConcealmentInfo *hConcealmentInfo,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
|
- const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
|
|
- const UCHAR lastLpdMode, const int FrameOk, const UINT flags);
|
|
-
|
|
-int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo,
|
|
- const int fBeforeApply);
|
|
-
|
|
-INT CConcealment_TDFading(
|
|
- int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
|
|
- FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1);
|
|
-
|
|
-#endif /* #ifndef CONCEAL_H */
|
|
--- a/libAACdec/src/conceal_types.h
|
|
+++ /dev/null
|
|
@@ -1,203 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s): Christian Griebel
|
|
-
|
|
- Description: Error concealment structs and types
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-#ifndef CONCEAL_TYPES_H
|
|
-#define CONCEAL_TYPES_H
|
|
-
|
|
-#include "machine_type.h"
|
|
-#include "common_fix.h"
|
|
-
|
|
-#include "rvlc_info.h"
|
|
-
|
|
-#include "usacdec_lpc.h"
|
|
-
|
|
-#define CONCEAL_MAX_NUM_FADE_FACTORS (32)
|
|
-
|
|
-#define FIXP_CNCL FIXP_DBL
|
|
-#define FL2FXCONST_CNCL FL2FXCONST_DBL
|
|
-#define FX_DBL2FX_CNCL
|
|
-#define FX_CNCL2FX_DBL
|
|
-#define CNCL_FRACT_BITS DFRACT_BITS
|
|
-
|
|
-/* Warning: Do not ever change these values. */
|
|
-typedef enum {
|
|
- ConcealMethodNone = -1,
|
|
- ConcealMethodMute = 0,
|
|
- ConcealMethodNoise = 1,
|
|
- ConcealMethodInter = 2,
|
|
- ConcealMethodTonal = 3
|
|
-
|
|
-} CConcealmentMethod;
|
|
-
|
|
-typedef enum {
|
|
- ConcealState_Ok,
|
|
- ConcealState_Single,
|
|
- ConcealState_FadeIn,
|
|
- ConcealState_Mute,
|
|
- ConcealState_FadeOut
|
|
-
|
|
-} CConcealmentState;
|
|
-
|
|
-typedef struct {
|
|
- FIXP_SGL fadeOutFactor[CONCEAL_MAX_NUM_FADE_FACTORS];
|
|
- FIXP_SGL fadeInFactor[CONCEAL_MAX_NUM_FADE_FACTORS];
|
|
-
|
|
- CConcealmentMethod method;
|
|
-
|
|
- int numFadeOutFrames;
|
|
- int numFadeInFrames;
|
|
- int numMuteReleaseFrames;
|
|
- FIXP_DBL comfortNoiseLevel;
|
|
-
|
|
-} CConcealParams;
|
|
-
|
|
-typedef enum {
|
|
- FADE_TIMEDOMAIN_TOSPECTRALMUTE = 1,
|
|
- FADE_TIMEDOMAIN_FROMSPECTRALMUTE,
|
|
- FADE_TIMEDOMAIN
|
|
-} TDfadingType;
|
|
-
|
|
-typedef struct {
|
|
- CConcealParams *pConcealParams;
|
|
-
|
|
- FIXP_CNCL spectralCoefficient[1024];
|
|
- SHORT specScale[8];
|
|
-
|
|
- INT iRandomPhase;
|
|
- INT prevFrameOk[2];
|
|
- INT cntValidFrames;
|
|
- INT cntFadeFrames; /* State for signal fade-in/out */
|
|
- /* States for signal fade-out of frames with more than one window/subframe -
|
|
- [0] used by Update CntFadeFrames mode of CConcealment_ApplyFadeOut, [1] used
|
|
- by FadeOut mode */
|
|
- int winGrpOffset[2]; /* State for signal fade-out of frames with more than one
|
|
- window/subframe */
|
|
- int attGrpOffset[2]; /* State for faster signal fade-out of frames with
|
|
- transient signal parts */
|
|
-
|
|
- SCHAR lastRenderMode;
|
|
-
|
|
- UCHAR windowShape;
|
|
- BLOCK_TYPE windowSequence;
|
|
- UCHAR lastWinGrpLen;
|
|
-
|
|
- CConcealmentState concealState;
|
|
- CConcealmentState concealState_old;
|
|
- FIXP_DBL fade_old; /* last fading factor */
|
|
- TDfadingType lastFadingType; /* last fading type */
|
|
-
|
|
- SHORT aRvlcPreviousScaleFactor[RVLC_MAX_SFB]; /* needed once per channel */
|
|
- UCHAR aRvlcPreviousCodebook[RVLC_MAX_SFB]; /* needed once per channel */
|
|
- SCHAR rvlcPreviousScaleFactorOK;
|
|
- SCHAR rvlcPreviousBlockType;
|
|
-
|
|
- FIXP_LPC lsf4[M_LP_FILTER_ORDER];
|
|
- FIXP_DBL last_tcx_gain;
|
|
- INT last_tcx_gain_e;
|
|
- ULONG TDNoiseSeed;
|
|
- FIXP_PCM TDNoiseStates[3];
|
|
- FIXP_SGL TDNoiseCoef[3];
|
|
- FIXP_SGL TDNoiseAtt;
|
|
-
|
|
-} CConcealmentInfo;
|
|
-
|
|
-#endif /* #ifndef CONCEAL_TYPES_H */
|
|
--- a/libAACdec/src/rvlc.cpp
|
|
+++ /dev/null
|
|
@@ -1,1217 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s):
|
|
-
|
|
- Description:
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-/*!
|
|
- \file
|
|
- \brief RVLC Decoder
|
|
- \author Robert Weidner
|
|
-*/
|
|
-
|
|
-#include "rvlc.h"
|
|
-
|
|
-#include "block.h"
|
|
-
|
|
-#include "aac_rom.h"
|
|
-#include "rvlcbit.h"
|
|
-#include "rvlcconceal.h"
|
|
-#include "aacdec_hcr.h"
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: rvlcInit
|
|
-
|
|
- description: init RVLC by data from channelinfo, which was decoded
|
|
-previously and set up pointers
|
|
------------------------------------------------------------------------------------------------
|
|
- input: - pointer rvlc structure
|
|
- - pointer channel info structure
|
|
- - pointer bitstream structure
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void rvlcInit(CErRvlcInfo *pRvlc,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- HANDLE_FDK_BITSTREAM bs) {
|
|
- /* RVLC common initialization part 2 of 2 */
|
|
- SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
|
|
- SHORT *pScfFwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd;
|
|
- SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd;
|
|
- SHORT *pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
|
|
- int bnds;
|
|
-
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcIntensityUsed = 0;
|
|
-
|
|
- pRvlc->numDecodedEscapeWordsEsc = 0;
|
|
- pRvlc->numDecodedEscapeWordsFwd = 0;
|
|
- pRvlc->numDecodedEscapeWordsBwd = 0;
|
|
-
|
|
- pRvlc->intensity_used = 0;
|
|
- pRvlc->errorLogRvlc = 0;
|
|
-
|
|
- pRvlc->conceal_max = CONCEAL_MAX_INIT;
|
|
- pRvlc->conceal_min = CONCEAL_MIN_INIT;
|
|
-
|
|
- pRvlc->conceal_max_esc = CONCEAL_MAX_INIT;
|
|
- pRvlc->conceal_min_esc = CONCEAL_MIN_INIT;
|
|
-
|
|
- pRvlc->pHuffTreeRvlcEscape = aHuffTreeRvlcEscape;
|
|
- pRvlc->pHuffTreeRvlCodewds = aHuffTreeRvlCodewds;
|
|
-
|
|
- /* init scf arrays (for savety (in case of there are only zero codebooks)) */
|
|
- for (bnds = 0; bnds < RVLC_MAX_SFB; bnds++) {
|
|
- pScfFwd[bnds] = 0;
|
|
- pScfBwd[bnds] = 0;
|
|
- pScfEsc[bnds] = 0;
|
|
- pScaleFactor[bnds] = 0;
|
|
- }
|
|
-
|
|
- /* set base bitstream ptr to the RVL-coded part (start of RVLC data (ESC 2))
|
|
- */
|
|
- FDKsyncCache(bs);
|
|
- pRvlc->bsAnchor = (INT)FDKgetValidBits(bs);
|
|
-
|
|
- pRvlc->bitstreamIndexRvlFwd =
|
|
- 0; /* first bit within RVL coded block as start address for forward
|
|
- decoding */
|
|
- pRvlc->bitstreamIndexRvlBwd =
|
|
- pRvlc->length_of_rvlc_sf - 1; /* last bit within RVL coded block as start
|
|
- address for backward decoding */
|
|
-
|
|
- /* skip RVLC-bitstream-part -- pointing now to escapes (if present) or to TNS
|
|
- * data (if present) */
|
|
- FDKpushFor(bs, pRvlc->length_of_rvlc_sf);
|
|
-
|
|
- if (pRvlc->sf_escapes_present != 0) {
|
|
- /* locate internal bitstream ptr at escapes (which is the second part) */
|
|
- FDKsyncCache(bs);
|
|
- pRvlc->bitstreamIndexEsc = pRvlc->bsAnchor - (INT)FDKgetValidBits(bs);
|
|
-
|
|
- /* skip escapeRVLC-bitstream-part -- pointing to TNS data (if present) to
|
|
- * make decoder continue */
|
|
- /* decoding of RVLC should work despite this second pushFor during
|
|
- * initialization because */
|
|
- /* bitstream initialization is valid for both ESC2 data parts (RVL-coded
|
|
- * values and ESC-coded values) */
|
|
- FDKpushFor(bs, pRvlc->length_of_rvlc_escapes);
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: rvlcCheckIntensityCb
|
|
-
|
|
- description: Check if a intensity codebook is used in the current channel.
|
|
------------------------------------------------------------------------------------------------
|
|
- input: - pointer rvlc structure
|
|
- - pointer channel info structure
|
|
------------------------------------------------------------------------------------------------
|
|
- output: - intensity_used: 0 no intensity codebook is used
|
|
- 1 intensity codebook is used
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void rvlcCheckIntensityCb(
|
|
- CErRvlcInfo *pRvlc, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
|
|
- int group, band, bnds;
|
|
-
|
|
- pRvlc->intensity_used = 0;
|
|
-
|
|
- for (group = 0; group < pRvlc->numWindowGroups; group++) {
|
|
- for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
|
|
- bnds = 16 * group + band;
|
|
- if ((pAacDecoderChannelInfo->pDynData->aCodeBook[bnds] ==
|
|
- INTENSITY_HCB) ||
|
|
- (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds] ==
|
|
- INTENSITY_HCB2)) {
|
|
- pRvlc->intensity_used = 1;
|
|
- break;
|
|
- }
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: rvlcDecodeEscapeWord
|
|
-
|
|
- description: Decode a huffman coded RVLC Escape-word. This value is part
|
|
-of a DPCM coded scalefactor.
|
|
------------------------------------------------------------------------------------------------
|
|
- input: - pointer rvlc structure
|
|
------------------------------------------------------------------------------------------------
|
|
- return: - a single RVLC-Escape value which had to be applied to a
|
|
-DPCM value (which has a absolute value of 7)
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static SCHAR rvlcDecodeEscapeWord(CErRvlcInfo *pRvlc, HANDLE_FDK_BITSTREAM bs) {
|
|
- int i;
|
|
- SCHAR value;
|
|
- UCHAR carryBit;
|
|
- UINT treeNode;
|
|
- UINT branchValue;
|
|
- UINT branchNode;
|
|
-
|
|
- INT *pBitstreamIndexEsc;
|
|
- const UINT *pEscTree;
|
|
-
|
|
- pEscTree = pRvlc->pHuffTreeRvlcEscape;
|
|
- pBitstreamIndexEsc = &(pRvlc->bitstreamIndexEsc);
|
|
- treeNode = *pEscTree; /* init at starting node */
|
|
-
|
|
- for (i = MAX_LEN_RVLC_ESCAPE_WORD - 1; i >= 0; i--) {
|
|
- carryBit =
|
|
- rvlcReadBitFromBitstream(bs, /* get next bit */
|
|
- pRvlc->bsAnchor, pBitstreamIndexEsc, FWD);
|
|
-
|
|
- CarryBitToBranchValue(carryBit, /* huffman decoding, do a single step in
|
|
- huffman decoding tree */
|
|
- treeNode, &branchValue, &branchNode);
|
|
-
|
|
- if ((branchNode & TEST_BIT_10) ==
|
|
- TEST_BIT_10) { /* test bit 10 ; if set --> a RVLC-escape-word is
|
|
- completely decoded */
|
|
- value = (SCHAR)branchNode & CLR_BIT_10;
|
|
- pRvlc->length_of_rvlc_escapes -= (MAX_LEN_RVLC_ESCAPE_WORD - i);
|
|
-
|
|
- if (pRvlc->length_of_rvlc_escapes < 0) {
|
|
- pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID;
|
|
- value = -1;
|
|
- }
|
|
-
|
|
- return value;
|
|
- } else {
|
|
- treeNode = *(
|
|
- pEscTree +
|
|
- branchValue); /* update treeNode for further step in decoding tree */
|
|
- }
|
|
- }
|
|
-
|
|
- pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID;
|
|
-
|
|
- return -1; /* should not be reached */
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: rvlcDecodeEscapes
|
|
-
|
|
- description: Decodes all huffman coded RVLC Escape Words.
|
|
- Here a difference to the pseudo-code-implementation from
|
|
-standard can be found. A while loop (and not two nested for loops) is used for
|
|
-two reasons:
|
|
-
|
|
- 1. The plain huffman encoded escapes are decoded before the
|
|
-RVL-coded scalefactors. Therefore the escapes are present in the second step
|
|
- when decoding the RVL-coded-scalefactor values in forward
|
|
-and backward direction.
|
|
-
|
|
- When the RVL-coded scalefactors are decoded and there a
|
|
-escape is needed, then it is just taken out of the array in ascending order.
|
|
-
|
|
- 2. It's faster.
|
|
------------------------------------------------------------------------------------------------
|
|
- input: - pointer rvlc structure
|
|
- - handle to FDK bitstream
|
|
------------------------------------------------------------------------------------------------
|
|
- return: - 0 ok the decoded escapes seem to be valid
|
|
- - 1 error there was a error detected during decoding escapes
|
|
- --> all escapes are invalid
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void rvlcDecodeEscapes(CErRvlcInfo *pRvlc, SHORT *pEsc,
|
|
- HANDLE_FDK_BITSTREAM bs) {
|
|
- SCHAR escWord;
|
|
- SCHAR escCnt = 0;
|
|
- SHORT *pEscBitCntSum;
|
|
-
|
|
- pEscBitCntSum = &(pRvlc->length_of_rvlc_escapes);
|
|
-
|
|
- /* Decode all RVLC-Escape words with a plain Huffman-Decoder */
|
|
- while (*pEscBitCntSum > 0) {
|
|
- escWord = rvlcDecodeEscapeWord(pRvlc, bs);
|
|
-
|
|
- if (escWord >= 0) {
|
|
- pEsc[escCnt] = escWord;
|
|
- escCnt++;
|
|
- } else {
|
|
- pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID;
|
|
- pRvlc->numDecodedEscapeWordsEsc = escCnt;
|
|
-
|
|
- return;
|
|
- }
|
|
- } /* all RVLC escapes decoded */
|
|
-
|
|
- pRvlc->numDecodedEscapeWordsEsc = escCnt;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: decodeRVLCodeword
|
|
-
|
|
- description: Decodes a RVL-coded dpcm-word (-part).
|
|
------------------------------------------------------------------------------------------------
|
|
- input: - FDK bitstream handle
|
|
- - pointer rvlc structure
|
|
------------------------------------------------------------------------------------------------
|
|
- return: - a dpcm value which is within range [0,1,..,14] in case of
|
|
-no errors. The offset of 7 must be subtracted to get a valid dpcm scalefactor
|
|
-value. In case of errors a forbidden codeword is detected --> returning -1
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-SCHAR decodeRVLCodeword(HANDLE_FDK_BITSTREAM bs, CErRvlcInfo *pRvlc) {
|
|
- int i;
|
|
- SCHAR value;
|
|
- UCHAR carryBit;
|
|
- UINT branchValue;
|
|
- UINT branchNode;
|
|
-
|
|
- const UINT *pRvlCodeTree = pRvlc->pHuffTreeRvlCodewds;
|
|
- UCHAR direction = pRvlc->direction;
|
|
- INT *pBitstrIndxRvl = pRvlc->pBitstrIndxRvl_RVL;
|
|
- UINT treeNode = *pRvlCodeTree;
|
|
-
|
|
- for (i = MAX_LEN_RVLC_CODE_WORD - 1; i >= 0; i--) {
|
|
- carryBit =
|
|
- rvlcReadBitFromBitstream(bs, /* get next bit */
|
|
- pRvlc->bsAnchor, pBitstrIndxRvl, direction);
|
|
-
|
|
- CarryBitToBranchValue(carryBit, /* huffman decoding, do a single step in
|
|
- huffman decoding tree */
|
|
- treeNode, &branchValue, &branchNode);
|
|
-
|
|
- if ((branchNode & TEST_BIT_10) ==
|
|
- TEST_BIT_10) { /* test bit 10 ; if set --> a
|
|
- RVLC-codeword is completely decoded
|
|
- */
|
|
- value = (SCHAR)(branchNode & CLR_BIT_10);
|
|
- *pRvlc->pRvlBitCnt_RVL -= (MAX_LEN_RVLC_CODE_WORD - i);
|
|
-
|
|
- /* check available bits for decoding */
|
|
- if (*pRvlc->pRvlBitCnt_RVL < 0) {
|
|
- if (direction == FWD) {
|
|
- pRvlc->errorLogRvlc |= RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_FWD;
|
|
- } else {
|
|
- pRvlc->errorLogRvlc |= RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_BWD;
|
|
- }
|
|
- value = -1; /* signalize an error in return value, because too many bits
|
|
- was decoded */
|
|
- }
|
|
-
|
|
- /* check max value of dpcm value */
|
|
- if (value > MAX_ALLOWED_DPCM_INDEX) {
|
|
- if (direction == FWD) {
|
|
- pRvlc->errorLogRvlc |= RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD;
|
|
- } else {
|
|
- pRvlc->errorLogRvlc |= RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD;
|
|
- }
|
|
- value = -1; /* signalize an error in return value, because a forbidden
|
|
- cw was detected*/
|
|
- }
|
|
-
|
|
- return value; /* return a dpcm value with offset +7 or an error status */
|
|
- } else {
|
|
- treeNode = *(
|
|
- pRvlCodeTree +
|
|
- branchValue); /* update treeNode for further step in decoding tree */
|
|
- }
|
|
- }
|
|
-
|
|
- return -1;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: rvlcDecodeForward
|
|
-
|
|
- description: Decode RVL-coded codewords in forward direction.
|
|
------------------------------------------------------------------------------------------------
|
|
- input: - pointer rvlc structure
|
|
- - pointer channel info structure
|
|
- - handle to FDK bitstream
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void rvlcDecodeForward(CErRvlcInfo *pRvlc,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- HANDLE_FDK_BITSTREAM bs) {
|
|
- int band = 0;
|
|
- int group = 0;
|
|
- int bnds = 0;
|
|
-
|
|
- SHORT dpcm;
|
|
-
|
|
- SHORT factor =
|
|
- pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET;
|
|
- SHORT position = -SF_OFFSET;
|
|
- SHORT noisenrg = pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain -
|
|
- SF_OFFSET - 90 - 256;
|
|
-
|
|
- SHORT *pScfFwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd;
|
|
- SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
|
|
- UCHAR *pEscFwdCnt = &(pRvlc->numDecodedEscapeWordsFwd);
|
|
-
|
|
- pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_fwd);
|
|
- pRvlc->pBitstrIndxRvl_RVL = &(pRvlc->bitstreamIndexRvlFwd);
|
|
-
|
|
- *pEscFwdCnt = 0;
|
|
- pRvlc->direction = FWD;
|
|
- pRvlc->noise_used = 0;
|
|
- pRvlc->sf_used = 0;
|
|
- pRvlc->lastScf = 0;
|
|
- pRvlc->lastNrg = 0;
|
|
- pRvlc->lastIs = 0;
|
|
-
|
|
- rvlcCheckIntensityCb(pRvlc, pAacDecoderChannelInfo);
|
|
-
|
|
- /* main loop fwd long */
|
|
- for (group = 0; group < pRvlc->numWindowGroups; group++) {
|
|
- for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
|
|
- bnds = 16 * group + band;
|
|
-
|
|
- switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
|
|
- case ZERO_HCB:
|
|
- pScfFwd[bnds] = 0;
|
|
- break;
|
|
-
|
|
- case INTENSITY_HCB2:
|
|
- case INTENSITY_HCB:
|
|
- /* store dpcm_is_position */
|
|
- dpcm = decodeRVLCodeword(bs, pRvlc);
|
|
- if (dpcm < 0) {
|
|
- pRvlc->conceal_max = bnds;
|
|
- return;
|
|
- }
|
|
- dpcm -= TABLE_OFFSET;
|
|
- if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
|
|
- if (pRvlc->length_of_rvlc_escapes) {
|
|
- pRvlc->conceal_max = bnds;
|
|
- return;
|
|
- } else {
|
|
- if (dpcm == MIN_RVL) {
|
|
- dpcm -= *pScfEsc++;
|
|
- } else {
|
|
- dpcm += *pScfEsc++;
|
|
- }
|
|
- (*pEscFwdCnt)++;
|
|
- if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
|
|
- pRvlc->conceal_max_esc = bnds;
|
|
- }
|
|
- }
|
|
- }
|
|
- position += dpcm;
|
|
- pScfFwd[bnds] = position;
|
|
- pRvlc->lastIs = position;
|
|
- break;
|
|
-
|
|
- case NOISE_HCB:
|
|
- if (pRvlc->noise_used == 0) {
|
|
- pRvlc->noise_used = 1;
|
|
- pRvlc->first_noise_band = bnds;
|
|
- noisenrg += pRvlc->dpcm_noise_nrg;
|
|
- pScfFwd[bnds] = 100 + noisenrg;
|
|
- pRvlc->lastNrg = noisenrg;
|
|
- } else {
|
|
- dpcm = decodeRVLCodeword(bs, pRvlc);
|
|
- if (dpcm < 0) {
|
|
- pRvlc->conceal_max = bnds;
|
|
- return;
|
|
- }
|
|
- dpcm -= TABLE_OFFSET;
|
|
- if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
|
|
- if (pRvlc->length_of_rvlc_escapes) {
|
|
- pRvlc->conceal_max = bnds;
|
|
- return;
|
|
- } else {
|
|
- if (dpcm == MIN_RVL) {
|
|
- dpcm -= *pScfEsc++;
|
|
- } else {
|
|
- dpcm += *pScfEsc++;
|
|
- }
|
|
- (*pEscFwdCnt)++;
|
|
- if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
|
|
- pRvlc->conceal_max_esc = bnds;
|
|
- }
|
|
- }
|
|
- }
|
|
- noisenrg += dpcm;
|
|
- pScfFwd[bnds] = 100 + noisenrg;
|
|
- pRvlc->lastNrg = noisenrg;
|
|
- }
|
|
- pAacDecoderChannelInfo->data.aac.PnsData.pnsUsed[bnds] = 1;
|
|
- break;
|
|
-
|
|
- default:
|
|
- pRvlc->sf_used = 1;
|
|
- dpcm = decodeRVLCodeword(bs, pRvlc);
|
|
- if (dpcm < 0) {
|
|
- pRvlc->conceal_max = bnds;
|
|
- return;
|
|
- }
|
|
- dpcm -= TABLE_OFFSET;
|
|
- if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
|
|
- if (pRvlc->length_of_rvlc_escapes) {
|
|
- pRvlc->conceal_max = bnds;
|
|
- return;
|
|
- } else {
|
|
- if (dpcm == MIN_RVL) {
|
|
- dpcm -= *pScfEsc++;
|
|
- } else {
|
|
- dpcm += *pScfEsc++;
|
|
- }
|
|
- (*pEscFwdCnt)++;
|
|
- if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
|
|
- pRvlc->conceal_max_esc = bnds;
|
|
- }
|
|
- }
|
|
- }
|
|
- factor += dpcm;
|
|
- pScfFwd[bnds] = factor;
|
|
- pRvlc->lastScf = factor;
|
|
- break;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- /* postfetch fwd long */
|
|
- if (pRvlc->intensity_used) {
|
|
- dpcm = decodeRVLCodeword(bs, pRvlc); /* dpcm_is_last_position */
|
|
- if (dpcm < 0) {
|
|
- pRvlc->conceal_max = bnds;
|
|
- return;
|
|
- }
|
|
- dpcm -= TABLE_OFFSET;
|
|
- if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
|
|
- if (pRvlc->length_of_rvlc_escapes) {
|
|
- pRvlc->conceal_max = bnds;
|
|
- return;
|
|
- } else {
|
|
- if (dpcm == MIN_RVL) {
|
|
- dpcm -= *pScfEsc++;
|
|
- } else {
|
|
- dpcm += *pScfEsc++;
|
|
- }
|
|
- (*pEscFwdCnt)++;
|
|
- if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
|
|
- pRvlc->conceal_max_esc = bnds;
|
|
- }
|
|
- }
|
|
- }
|
|
- pRvlc->dpcm_is_last_position = dpcm;
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: rvlcDecodeBackward
|
|
-
|
|
- description: Decode RVL-coded codewords in backward direction.
|
|
------------------------------------------------------------------------------------------------
|
|
- input: - pointer rvlc structure
|
|
- - pointer channel info structure
|
|
- - handle FDK bitstream
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- HANDLE_FDK_BITSTREAM bs) {
|
|
- SHORT band, group, dpcm, offset;
|
|
- SHORT bnds = pRvlc->maxSfbTransmitted - 1;
|
|
-
|
|
- SHORT factor = pRvlc->rev_global_gain - SF_OFFSET;
|
|
- SHORT position = pRvlc->dpcm_is_last_position - SF_OFFSET;
|
|
- SHORT noisenrg = pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position -
|
|
- SF_OFFSET - 90 - 256;
|
|
-
|
|
- SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd;
|
|
- SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
|
|
- UCHAR *pEscEscCnt = &(pRvlc->numDecodedEscapeWordsEsc);
|
|
- UCHAR *pEscBwdCnt = &(pRvlc->numDecodedEscapeWordsBwd);
|
|
-
|
|
- pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_bwd);
|
|
- pRvlc->pBitstrIndxRvl_RVL = &(pRvlc->bitstreamIndexRvlBwd);
|
|
-
|
|
- *pEscBwdCnt = 0;
|
|
- pRvlc->direction = BWD;
|
|
- pScfEsc += *pEscEscCnt - 1; /* set pScfEsc to last entry */
|
|
- pRvlc->firstScf = 0;
|
|
- pRvlc->firstNrg = 0;
|
|
- pRvlc->firstIs = 0;
|
|
-
|
|
- /* prefetch long BWD */
|
|
- if (pRvlc->intensity_used) {
|
|
- dpcm = decodeRVLCodeword(bs, pRvlc); /* dpcm_is_last_position */
|
|
- if (dpcm < 0) {
|
|
- pRvlc->dpcm_is_last_position = 0;
|
|
- pRvlc->conceal_min = bnds;
|
|
- return;
|
|
- }
|
|
- dpcm -= TABLE_OFFSET;
|
|
- if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
|
|
- if (pRvlc->length_of_rvlc_escapes) {
|
|
- pRvlc->conceal_min = bnds;
|
|
- return;
|
|
- } else {
|
|
- if (dpcm == MIN_RVL) {
|
|
- dpcm -= *pScfEsc--;
|
|
- } else {
|
|
- dpcm += *pScfEsc--;
|
|
- }
|
|
- (*pEscBwdCnt)++;
|
|
- if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
|
|
- pRvlc->conceal_min_esc = bnds;
|
|
- }
|
|
- }
|
|
- }
|
|
- pRvlc->dpcm_is_last_position = dpcm;
|
|
- }
|
|
-
|
|
- /* main loop long BWD */
|
|
- for (group = pRvlc->numWindowGroups - 1; group >= 0; group--) {
|
|
- for (band = pRvlc->maxSfbTransmitted - 1; band >= 0; band--) {
|
|
- bnds = 16 * group + band;
|
|
- if ((band == 0) && (pRvlc->numWindowGroups != 1))
|
|
- offset = 16 - pRvlc->maxSfbTransmitted + 1;
|
|
- else
|
|
- offset = 1;
|
|
-
|
|
- switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
|
|
- case ZERO_HCB:
|
|
- pScfBwd[bnds] = 0;
|
|
- break;
|
|
-
|
|
- case INTENSITY_HCB2:
|
|
- case INTENSITY_HCB:
|
|
- /* store dpcm_is_position */
|
|
- dpcm = decodeRVLCodeword(bs, pRvlc);
|
|
- if (dpcm < 0) {
|
|
- pScfBwd[bnds] = position;
|
|
- pRvlc->conceal_min = fMax(0, bnds - offset);
|
|
- return;
|
|
- }
|
|
- dpcm -= TABLE_OFFSET;
|
|
- if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
|
|
- if (pRvlc->length_of_rvlc_escapes) {
|
|
- pScfBwd[bnds] = position;
|
|
- pRvlc->conceal_min = fMax(0, bnds - offset);
|
|
- return;
|
|
- } else {
|
|
- if (dpcm == MIN_RVL) {
|
|
- dpcm -= *pScfEsc--;
|
|
- } else {
|
|
- dpcm += *pScfEsc--;
|
|
- }
|
|
- (*pEscBwdCnt)++;
|
|
- if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
|
|
- pRvlc->conceal_min_esc = fMax(0, bnds - offset);
|
|
- }
|
|
- }
|
|
- }
|
|
- pScfBwd[bnds] = position;
|
|
- position -= dpcm;
|
|
- pRvlc->firstIs = position;
|
|
- break;
|
|
-
|
|
- case NOISE_HCB:
|
|
- if (bnds == pRvlc->first_noise_band) {
|
|
- pScfBwd[bnds] =
|
|
- pRvlc->dpcm_noise_nrg +
|
|
- pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain -
|
|
- SF_OFFSET - 90 - 256;
|
|
- pRvlc->firstNrg = pScfBwd[bnds];
|
|
- } else {
|
|
- dpcm = decodeRVLCodeword(bs, pRvlc);
|
|
- if (dpcm < 0) {
|
|
- pScfBwd[bnds] = noisenrg;
|
|
- pRvlc->conceal_min = fMax(0, bnds - offset);
|
|
- return;
|
|
- }
|
|
- dpcm -= TABLE_OFFSET;
|
|
- if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
|
|
- if (pRvlc->length_of_rvlc_escapes) {
|
|
- pScfBwd[bnds] = noisenrg;
|
|
- pRvlc->conceal_min = fMax(0, bnds - offset);
|
|
- return;
|
|
- } else {
|
|
- if (dpcm == MIN_RVL) {
|
|
- dpcm -= *pScfEsc--;
|
|
- } else {
|
|
- dpcm += *pScfEsc--;
|
|
- }
|
|
- (*pEscBwdCnt)++;
|
|
- if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
|
|
- pRvlc->conceal_min_esc = fMax(0, bnds - offset);
|
|
- }
|
|
- }
|
|
- }
|
|
- pScfBwd[bnds] = noisenrg;
|
|
- noisenrg -= dpcm;
|
|
- pRvlc->firstNrg = noisenrg;
|
|
- }
|
|
- break;
|
|
-
|
|
- default:
|
|
- dpcm = decodeRVLCodeword(bs, pRvlc);
|
|
- if (dpcm < 0) {
|
|
- pScfBwd[bnds] = factor;
|
|
- pRvlc->conceal_min = fMax(0, bnds - offset);
|
|
- return;
|
|
- }
|
|
- dpcm -= TABLE_OFFSET;
|
|
- if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
|
|
- if (pRvlc->length_of_rvlc_escapes) {
|
|
- pScfBwd[bnds] = factor;
|
|
- pRvlc->conceal_min = fMax(0, bnds - offset);
|
|
- return;
|
|
- } else {
|
|
- if (dpcm == MIN_RVL) {
|
|
- dpcm -= *pScfEsc--;
|
|
- } else {
|
|
- dpcm += *pScfEsc--;
|
|
- }
|
|
- (*pEscBwdCnt)++;
|
|
- if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
|
|
- pRvlc->conceal_min_esc = fMax(0, bnds - offset);
|
|
- }
|
|
- }
|
|
- }
|
|
- pScfBwd[bnds] = factor;
|
|
- factor -= dpcm;
|
|
- pRvlc->firstScf = factor;
|
|
- break;
|
|
- }
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: rvlcFinalErrorDetection
|
|
-
|
|
- description: Call RVLC concealment if error was detected in decoding
|
|
-process
|
|
------------------------------------------------------------------------------------------------
|
|
- input: - pointer rvlc structure
|
|
- - pointer channel info structure
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void rvlcFinalErrorDetection(
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
|
|
- CErRvlcInfo *pRvlc =
|
|
- &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
|
|
- UCHAR ErrorStatusComplete = 0;
|
|
- UCHAR ErrorStatusLengthFwd = 0;
|
|
- UCHAR ErrorStatusLengthBwd = 0;
|
|
- UCHAR ErrorStatusLengthEscapes = 0;
|
|
- UCHAR ErrorStatusFirstScf = 0;
|
|
- UCHAR ErrorStatusLastScf = 0;
|
|
- UCHAR ErrorStatusFirstNrg = 0;
|
|
- UCHAR ErrorStatusLastNrg = 0;
|
|
- UCHAR ErrorStatusFirstIs = 0;
|
|
- UCHAR ErrorStatusLastIs = 0;
|
|
- UCHAR ErrorStatusForbiddenCwFwd = 0;
|
|
- UCHAR ErrorStatusForbiddenCwBwd = 0;
|
|
- UCHAR ErrorStatusNumEscapesFwd = 0;
|
|
- UCHAR ErrorStatusNumEscapesBwd = 0;
|
|
- UCHAR ConcealStatus = 1;
|
|
- UCHAR currentBlockType; /* short: 0, not short: 1*/
|
|
-
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 1;
|
|
-
|
|
- /* invalid escape words, bit counter unequal zero, forbidden codeword detected
|
|
- */
|
|
- if (pRvlc->errorLogRvlc & RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD)
|
|
- ErrorStatusForbiddenCwFwd = 1;
|
|
-
|
|
- if (pRvlc->errorLogRvlc & RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD)
|
|
- ErrorStatusForbiddenCwBwd = 1;
|
|
-
|
|
- /* bit counter forward unequal zero */
|
|
- if (pRvlc->length_of_rvlc_sf_fwd) ErrorStatusLengthFwd = 1;
|
|
-
|
|
- /* bit counter backward unequal zero */
|
|
- if (pRvlc->length_of_rvlc_sf_bwd) ErrorStatusLengthBwd = 1;
|
|
-
|
|
- /* bit counter escape sequences unequal zero */
|
|
- if (pRvlc->sf_escapes_present)
|
|
- if (pRvlc->length_of_rvlc_escapes) ErrorStatusLengthEscapes = 1;
|
|
-
|
|
- if (pRvlc->sf_used) {
|
|
- /* first decoded scf does not match to global gain in backward direction */
|
|
- if (pRvlc->firstScf !=
|
|
- (pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET))
|
|
- ErrorStatusFirstScf = 1;
|
|
-
|
|
- /* last decoded scf does not match to rev global gain in forward direction
|
|
- */
|
|
- if (pRvlc->lastScf != (pRvlc->rev_global_gain - SF_OFFSET))
|
|
- ErrorStatusLastScf = 1;
|
|
- }
|
|
-
|
|
- if (pRvlc->noise_used) {
|
|
- /* first decoded nrg does not match to dpcm_noise_nrg in backward direction
|
|
- */
|
|
- if (pRvlc->firstNrg !=
|
|
- (pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain +
|
|
- pRvlc->dpcm_noise_nrg - SF_OFFSET - 90 - 256))
|
|
- ErrorStatusFirstNrg = 1;
|
|
-
|
|
- /* last decoded nrg does not match to dpcm_noise_last_position in forward
|
|
- * direction */
|
|
- if (pRvlc->lastNrg !=
|
|
- (pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position - SF_OFFSET -
|
|
- 90 - 256))
|
|
- ErrorStatusLastNrg = 1;
|
|
- }
|
|
-
|
|
- if (pRvlc->intensity_used) {
|
|
- /* first decoded is position does not match in backward direction */
|
|
- if (pRvlc->firstIs != (-SF_OFFSET)) ErrorStatusFirstIs = 1;
|
|
-
|
|
- /* last decoded is position does not match in forward direction */
|
|
- if (pRvlc->lastIs != (pRvlc->dpcm_is_last_position - SF_OFFSET))
|
|
- ErrorStatusLastIs = 1;
|
|
- }
|
|
-
|
|
- /* decoded escapes and used escapes in forward direction do not fit */
|
|
- if ((pRvlc->numDecodedEscapeWordsFwd != pRvlc->numDecodedEscapeWordsEsc) &&
|
|
- (pRvlc->conceal_max == CONCEAL_MAX_INIT)) {
|
|
- ErrorStatusNumEscapesFwd = 1;
|
|
- }
|
|
-
|
|
- /* decoded escapes and used escapes in backward direction do not fit */
|
|
- if ((pRvlc->numDecodedEscapeWordsBwd != pRvlc->numDecodedEscapeWordsEsc) &&
|
|
- (pRvlc->conceal_min == CONCEAL_MIN_INIT)) {
|
|
- ErrorStatusNumEscapesBwd = 1;
|
|
- }
|
|
-
|
|
- if (ErrorStatusLengthEscapes ||
|
|
- (((pRvlc->conceal_max == CONCEAL_MAX_INIT) &&
|
|
- (pRvlc->numDecodedEscapeWordsFwd != pRvlc->numDecodedEscapeWordsEsc) &&
|
|
- (ErrorStatusLastScf || ErrorStatusLastNrg || ErrorStatusLastIs))
|
|
-
|
|
- &&
|
|
-
|
|
- ((pRvlc->conceal_min == CONCEAL_MIN_INIT) &&
|
|
- (pRvlc->numDecodedEscapeWordsBwd != pRvlc->numDecodedEscapeWordsEsc) &&
|
|
- (ErrorStatusFirstScf || ErrorStatusFirstNrg || ErrorStatusFirstIs))) ||
|
|
- ((pRvlc->conceal_max == CONCEAL_MAX_INIT) &&
|
|
- ((pRvlc->rev_global_gain - SF_OFFSET - pRvlc->lastScf) < -15)) ||
|
|
- ((pRvlc->conceal_min == CONCEAL_MIN_INIT) &&
|
|
- ((pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET -
|
|
- pRvlc->firstScf) < -15))) {
|
|
- if ((pRvlc->conceal_max == CONCEAL_MAX_INIT) ||
|
|
- (pRvlc->conceal_min == CONCEAL_MIN_INIT)) {
|
|
- pRvlc->conceal_max = 0;
|
|
- pRvlc->conceal_min = fMax(
|
|
- 0, (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1);
|
|
- } else {
|
|
- pRvlc->conceal_max = fMin(pRvlc->conceal_max, pRvlc->conceal_max_esc);
|
|
- pRvlc->conceal_min = fMax(pRvlc->conceal_min, pRvlc->conceal_min_esc);
|
|
- }
|
|
- }
|
|
-
|
|
- ErrorStatusComplete = ErrorStatusLastScf || ErrorStatusFirstScf ||
|
|
- ErrorStatusLastNrg || ErrorStatusFirstNrg ||
|
|
- ErrorStatusLastIs || ErrorStatusFirstIs ||
|
|
- ErrorStatusForbiddenCwFwd ||
|
|
- ErrorStatusForbiddenCwBwd || ErrorStatusLengthFwd ||
|
|
- ErrorStatusLengthBwd || ErrorStatusLengthEscapes ||
|
|
- ErrorStatusNumEscapesFwd || ErrorStatusNumEscapesBwd;
|
|
-
|
|
- currentBlockType =
|
|
- (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) ? 0
|
|
- : 1;
|
|
-
|
|
- if (!ErrorStatusComplete) {
|
|
- int band;
|
|
- int group;
|
|
- int bnds;
|
|
- int lastSfbIndex;
|
|
-
|
|
- lastSfbIndex = (pRvlc->numWindowGroups > 1) ? 16 : 64;
|
|
-
|
|
- for (group = 0; group < pRvlc->numWindowGroups; group++) {
|
|
- for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
|
|
- bnds = 16 * group + band;
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- }
|
|
- }
|
|
-
|
|
- for (group = 0; group < pRvlc->numWindowGroups; group++) {
|
|
- for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
|
|
- bnds = 16 * group + band;
|
|
- pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] =
|
|
- pAacDecoderChannelInfo->pDynData->aCodeBook[bnds];
|
|
- }
|
|
- for (; band < lastSfbIndex; band++) {
|
|
- bnds = 16 * group + band;
|
|
- FDK_ASSERT(bnds >= 0 && bnds < RVLC_MAX_SFB);
|
|
- pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] = ZERO_HCB;
|
|
- }
|
|
- }
|
|
- } else {
|
|
- int band;
|
|
- int group;
|
|
-
|
|
- /* A single bit error was detected in decoding of dpcm values. It also could
|
|
- be an error with more bits in decoding of escapes and dpcm values whereby
|
|
- an illegal codeword followed not directly after the corrupted bits but
|
|
- just after decoding some more (wrong) scalefactors. Use the smaller
|
|
- scalefactor from forward decoding, backward decoding and previous frame.
|
|
- */
|
|
- if (((pRvlc->conceal_min != CONCEAL_MIN_INIT) ||
|
|
- (pRvlc->conceal_max != CONCEAL_MAX_INIT)) &&
|
|
- (pRvlc->conceal_min <= pRvlc->conceal_max) &&
|
|
- (pAacDecoderStaticChannelInfo->concealmentInfo.rvlcPreviousBlockType ==
|
|
- currentBlockType) &&
|
|
- pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .rvlcPreviousScaleFactorOK &&
|
|
- pRvlc->sf_concealment && ConcealStatus) {
|
|
- BidirectionalEstimation_UseScfOfPrevFrameAsReference(
|
|
- pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo);
|
|
- ConcealStatus = 0;
|
|
- }
|
|
-
|
|
- /* A single bit error was detected in decoding of dpcm values. It also could
|
|
- be an error with more bits in decoding of escapes and dpcm values whereby
|
|
- an illegal codeword followed not directly after the corrupted bits but
|
|
- just after decoding some more (wrong) scalefactors. Use the smaller
|
|
- scalefactor from forward and backward decoding. */
|
|
- if ((pRvlc->conceal_min <= pRvlc->conceal_max) &&
|
|
- ((pRvlc->conceal_min != CONCEAL_MIN_INIT) ||
|
|
- (pRvlc->conceal_max != CONCEAL_MAX_INIT)) &&
|
|
- !(pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .rvlcPreviousScaleFactorOK &&
|
|
- pRvlc->sf_concealment &&
|
|
- (pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .rvlcPreviousBlockType == currentBlockType)) &&
|
|
- ConcealStatus) {
|
|
- BidirectionalEstimation_UseLowerScfOfCurrentFrame(pAacDecoderChannelInfo);
|
|
- ConcealStatus = 0;
|
|
- }
|
|
-
|
|
- /* No errors were detected in decoding of escapes and dpcm values however
|
|
- the first and last value of a group (is,nrg,sf) is incorrect */
|
|
- if ((pRvlc->conceal_min <= pRvlc->conceal_max) &&
|
|
- ((ErrorStatusLastScf && ErrorStatusFirstScf) ||
|
|
- (ErrorStatusLastNrg && ErrorStatusFirstNrg) ||
|
|
- (ErrorStatusLastIs && ErrorStatusFirstIs)) &&
|
|
- !(ErrorStatusForbiddenCwFwd || ErrorStatusForbiddenCwBwd ||
|
|
- ErrorStatusLengthEscapes) &&
|
|
- ConcealStatus) {
|
|
- StatisticalEstimation(pAacDecoderChannelInfo);
|
|
- ConcealStatus = 0;
|
|
- }
|
|
-
|
|
- /* A error with more bits in decoding of escapes and dpcm values was
|
|
- detected. Use the smaller scalefactor from forward decoding, backward
|
|
- decoding and previous frame. */
|
|
- if ((pRvlc->conceal_min <= pRvlc->conceal_max) &&
|
|
- pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .rvlcPreviousScaleFactorOK &&
|
|
- pRvlc->sf_concealment &&
|
|
- (pAacDecoderStaticChannelInfo->concealmentInfo.rvlcPreviousBlockType ==
|
|
- currentBlockType) &&
|
|
- ConcealStatus) {
|
|
- PredictiveInterpolation(pAacDecoderChannelInfo,
|
|
- pAacDecoderStaticChannelInfo);
|
|
- ConcealStatus = 0;
|
|
- }
|
|
-
|
|
- /* Call frame concealment, because no better strategy was found. Setting the
|
|
- scalefactors to zero is done for debugging purposes */
|
|
- if (ConcealStatus) {
|
|
- for (group = 0; group < pRvlc->numWindowGroups; group++) {
|
|
- for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[16 * group + band] = 0;
|
|
- }
|
|
- }
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac
|
|
- .rvlcCurrentScaleFactorOK = 0;
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: CRvlc_Read
|
|
-
|
|
- description: Read RVLC ESC1 data (side info) from bitstream.
|
|
------------------------------------------------------------------------------------------------
|
|
- input: - pointer rvlc structure
|
|
- - pointer channel info structure
|
|
- - pointer bitstream structure
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-void CRvlc_Read(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- HANDLE_FDK_BITSTREAM bs) {
|
|
- CErRvlcInfo *pRvlc =
|
|
- &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
|
|
-
|
|
- int group, band;
|
|
-
|
|
- /* RVLC long specific initialization Init part 1 of 2 */
|
|
- pRvlc->numWindowGroups = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
|
|
- pRvlc->maxSfbTransmitted =
|
|
- GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
|
|
- pRvlc->noise_used = 0; /* noise detection */
|
|
- pRvlc->dpcm_noise_nrg = 0; /* only for debugging */
|
|
- pRvlc->dpcm_noise_last_position = 0; /* only for debugging */
|
|
- pRvlc->length_of_rvlc_escapes =
|
|
- -1; /* default value is used for error detection and concealment */
|
|
-
|
|
- /* read only error sensitivity class 1 data (ESC 1 - data) */
|
|
- pRvlc->sf_concealment = FDKreadBits(bs, 1); /* #1 */
|
|
- pRvlc->rev_global_gain = FDKreadBits(bs, 8); /* #2 */
|
|
-
|
|
- if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) {
|
|
- pRvlc->length_of_rvlc_sf = FDKreadBits(bs, 11); /* #3 */
|
|
- } else {
|
|
- pRvlc->length_of_rvlc_sf = FDKreadBits(bs, 9); /* #3 */
|
|
- }
|
|
-
|
|
- /* check if noise codebook is used */
|
|
- for (group = 0; group < pRvlc->numWindowGroups; group++) {
|
|
- for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
|
|
- if (pAacDecoderChannelInfo->pDynData->aCodeBook[16 * group + band] ==
|
|
- NOISE_HCB) {
|
|
- pRvlc->noise_used = 1;
|
|
- break;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- if (pRvlc->noise_used)
|
|
- pRvlc->dpcm_noise_nrg = FDKreadBits(bs, 9); /* #4 PNS */
|
|
-
|
|
- pRvlc->sf_escapes_present = FDKreadBits(bs, 1); /* #5 */
|
|
-
|
|
- if (pRvlc->sf_escapes_present) {
|
|
- pRvlc->length_of_rvlc_escapes = FDKreadBits(bs, 8); /* #6 */
|
|
- }
|
|
-
|
|
- if (pRvlc->noise_used) {
|
|
- pRvlc->dpcm_noise_last_position = FDKreadBits(bs, 9); /* #7 PNS */
|
|
- pRvlc->length_of_rvlc_sf -= 9;
|
|
- }
|
|
-
|
|
- pRvlc->length_of_rvlc_sf_fwd = pRvlc->length_of_rvlc_sf;
|
|
- pRvlc->length_of_rvlc_sf_bwd = pRvlc->length_of_rvlc_sf;
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: CRvlc_Decode
|
|
-
|
|
- description: Decode rvlc data
|
|
- The function reads both the escape sequences and the
|
|
-scalefactors in forward and backward direction. If an error occured during
|
|
-decoding process which can not be concealed with the rvlc concealment frame
|
|
-concealment will be initiated. Then the element "rvlcCurrentScaleFactorOK" in
|
|
-the decoder channel info is set to 0 otherwise it is set to 1.
|
|
------------------------------------------------------------------------------------------------
|
|
- input: - pointer rvlc structure
|
|
- - pointer channel info structure
|
|
- - pointer to persistent channel info structure
|
|
- - pointer bitstream structure
|
|
------------------------------------------------------------------------------------------------
|
|
- return: ErrorStatus = AAC_DEC_OK
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-void CRvlc_Decode(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
|
- HANDLE_FDK_BITSTREAM bs) {
|
|
- CErRvlcInfo *pRvlc =
|
|
- &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
|
|
- INT bitCntOffst;
|
|
- INT saveBitCnt;
|
|
-
|
|
- rvlcInit(pRvlc, pAacDecoderChannelInfo, bs);
|
|
-
|
|
- /* save bitstream position */
|
|
- saveBitCnt = (INT)FDKgetValidBits(bs);
|
|
-
|
|
- if (pRvlc->sf_escapes_present)
|
|
- rvlcDecodeEscapes(
|
|
- pRvlc, pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc, bs);
|
|
-
|
|
- rvlcDecodeForward(pRvlc, pAacDecoderChannelInfo, bs);
|
|
- rvlcDecodeBackward(pRvlc, pAacDecoderChannelInfo, bs);
|
|
- rvlcFinalErrorDetection(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo);
|
|
-
|
|
- pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcIntensityUsed =
|
|
- pRvlc->intensity_used;
|
|
- pAacDecoderChannelInfo->data.aac.PnsData.PnsActive = pRvlc->noise_used;
|
|
-
|
|
- /* restore bitstream position */
|
|
- bitCntOffst = (INT)FDKgetValidBits(bs) - saveBitCnt;
|
|
- if (bitCntOffst) {
|
|
- FDKpushBiDirectional(bs, bitCntOffst);
|
|
- }
|
|
-}
|
|
-
|
|
-void CRvlc_ElementCheck(
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
|
|
- const UINT flags, const INT elChannels) {
|
|
- int ch;
|
|
-
|
|
- /* Required for MPS residuals. */
|
|
- if (pAacDecoderStaticChannelInfo == NULL) {
|
|
- return;
|
|
- }
|
|
-
|
|
- /* RVLC specific sanity checks */
|
|
- if ((flags & AC_ER_RVLC) && (elChannels == 2)) { /* to be reviewed */
|
|
- if (((pAacDecoderChannelInfo[0]
|
|
- ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0) ||
|
|
- (pAacDecoderChannelInfo[1]
|
|
- ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0)) &&
|
|
- pAacDecoderChannelInfo[0]->pComData->jointStereoData.MsMaskPresent) {
|
|
- pAacDecoderChannelInfo[0]
|
|
- ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0;
|
|
- pAacDecoderChannelInfo[1]
|
|
- ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0;
|
|
- }
|
|
-
|
|
- if ((pAacDecoderChannelInfo[0]
|
|
- ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0) &&
|
|
- (pAacDecoderChannelInfo[1]
|
|
- ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 1) &&
|
|
- (pAacDecoderChannelInfo[1]
|
|
- ->pDynData->specificTo.aac.rvlcIntensityUsed == 1)) {
|
|
- pAacDecoderChannelInfo[1]
|
|
- ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0;
|
|
- }
|
|
- }
|
|
-
|
|
- for (ch = 0; ch < elChannels; ch++) {
|
|
- pAacDecoderStaticChannelInfo[ch]->concealmentInfo.rvlcPreviousBlockType =
|
|
- (GetWindowSequence(&pAacDecoderChannelInfo[ch]->icsInfo) == BLOCK_SHORT)
|
|
- ? 0
|
|
- : 1;
|
|
- if (flags & AC_ER_RVLC) {
|
|
- pAacDecoderStaticChannelInfo[ch]
|
|
- ->concealmentInfo.rvlcPreviousScaleFactorOK =
|
|
- pAacDecoderChannelInfo[ch]
|
|
- ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK;
|
|
- } else {
|
|
- pAacDecoderStaticChannelInfo[ch]
|
|
- ->concealmentInfo.rvlcPreviousScaleFactorOK = 0;
|
|
- }
|
|
- }
|
|
-}
|
|
--- a/libAACdec/src/rvlc.h
|
|
+++ /dev/null
|
|
@@ -1,153 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s):
|
|
-
|
|
- Description:
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-/*!
|
|
- \file
|
|
- \brief Defines structures and prototypes for RVLC
|
|
- \author Robert Weidner
|
|
-*/
|
|
-
|
|
-#ifndef RVLC_H
|
|
-#define RVLC_H
|
|
-
|
|
-#include "aacdecoder.h"
|
|
-#include "channel.h"
|
|
-#include "rvlc_info.h"
|
|
-
|
|
-/* ------------------------------------------------------------------- */
|
|
-/* errorLogRvlc: A word of 32 bits used for logging possible errors */
|
|
-/* within RVLC in case of distorted bitstreams. */
|
|
-/* ------------------------------------------------------------------- */
|
|
-#define RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID \
|
|
- 0x80000000 /* ESC-Dec During RVLC-Escape-decoding there have been more \
|
|
- bits decoded as there are available */
|
|
-#define RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_FWD \
|
|
- 0x40000000 /* RVL-Dec negative sum-bitcounter during RVL-fwd-decoding \
|
|
- (long+shrt) */
|
|
-#define RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_BWD \
|
|
- 0x20000000 /* RVL-Dec negative sum-bitcounter during RVL-fwd-decoding \
|
|
- (long+shrt) */
|
|
-#define RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD \
|
|
- 0x08000000 /* RVL-Dec forbidden codeword detected fwd (long+shrt) */
|
|
-#define RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD \
|
|
- 0x04000000 /* RVL-Dec forbidden codeword detected bwd (long+shrt) */
|
|
-
|
|
-void CRvlc_Read(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- HANDLE_FDK_BITSTREAM bs);
|
|
-
|
|
-void CRvlc_Decode(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
|
- HANDLE_FDK_BITSTREAM bs);
|
|
-
|
|
-/**
|
|
- * \brief performe sanity checks to the channel data corresponding to one
|
|
- * channel element.
|
|
- * \param pAacDecoderChannelInfo
|
|
- * \param pAacDecoderStaticChannelInfo
|
|
- * \param elChannels amount of channels of the channel element.
|
|
- */
|
|
-void CRvlc_ElementCheck(
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
|
|
- const UINT flags, const INT elChannels);
|
|
-
|
|
-#endif /* RVLC_H */
|
|
--- a/libAACdec/src/rvlc_info.h
|
|
+++ /dev/null
|
|
@@ -1,204 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s):
|
|
-
|
|
- Description:
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-/*!
|
|
- \file
|
|
- \brief Defines structures for RVLC
|
|
- \author Robert Weidner
|
|
-*/
|
|
-#ifndef RVLC_INFO_H
|
|
-#define RVLC_INFO_H
|
|
-
|
|
-#define FWD 0 /* bitstream decoding direction forward (RVL coded part) */
|
|
-#define BWD 1 /* bitstream decoding direction backward (RVL coded part) */
|
|
-
|
|
-#define MAX_RVL 7 /* positive RVLC escape */
|
|
-#define MIN_RVL -7 /* negative RVLC escape */
|
|
-#define MAX_ALLOWED_DPCM_INDEX \
|
|
- 14 /* the maximum allowed index of a decoded dpcm value (offset \
|
|
- 'TABLE_OFFSET' incl --> must be subtracted) */
|
|
-#define TABLE_OFFSET \
|
|
- 7 /* dpcm offset of valid output values of rvl table decoding, the rvl table \
|
|
- ouly returns positive values, therefore the offset */
|
|
-#define MAX_LEN_RVLC_CODE_WORD 9 /* max length of a RVL codeword in bits */
|
|
-#define MAX_LEN_RVLC_ESCAPE_WORD \
|
|
- 20 /* max length of huffman coded RVLC escape word in bits */
|
|
-
|
|
-#define DPCM_NOISE_NRG_BITS 9
|
|
-#define SF_OFFSET 100 /* offset for correcting scf value */
|
|
-
|
|
-#define CONCEAL_MAX_INIT 1311 /* arbitrary value */
|
|
-#define CONCEAL_MIN_INIT -1311 /* arbitrary value */
|
|
-
|
|
-#define RVLC_MAX_SFB ((8) * (16))
|
|
-
|
|
-/* sideinfo of RVLC */
|
|
-typedef struct {
|
|
- /* ------- ESC 1 Data: --------- */ /* order of RVLC-bitstream components in
|
|
- bitstream (RVLC-initialization), every
|
|
- component appears only once in
|
|
- bitstream */
|
|
- INT sf_concealment; /* 1 */
|
|
- INT rev_global_gain; /* 2 */
|
|
- SHORT length_of_rvlc_sf; /* 3 */ /* original value, gets modified
|
|
- (subtract 9) in case of noise
|
|
- (PNS); is kept for later use */
|
|
- INT dpcm_noise_nrg; /* 4 optional */
|
|
- INT sf_escapes_present; /* 5 */
|
|
- SHORT length_of_rvlc_escapes; /* 6 optional */
|
|
- INT dpcm_noise_last_position; /* 7 optional */
|
|
-
|
|
- INT dpcm_is_last_position;
|
|
-
|
|
- SHORT length_of_rvlc_sf_fwd; /* length_of_rvlc_sf used for forward decoding */
|
|
- SHORT
|
|
- length_of_rvlc_sf_bwd; /* length_of_rvlc_sf used for backward decoding */
|
|
-
|
|
- /* for RVL-Codeword decoder to distinguish between fwd and bwd decoding */
|
|
- SHORT *pRvlBitCnt_RVL;
|
|
- INT *pBitstrIndxRvl_RVL;
|
|
-
|
|
- UCHAR numWindowGroups;
|
|
- UCHAR maxSfbTransmitted;
|
|
- UCHAR first_noise_group;
|
|
- UCHAR first_noise_band;
|
|
- UCHAR direction;
|
|
-
|
|
- /* bitstream indices */
|
|
- INT bsAnchor; /* hcr bit buffer reference index */
|
|
- INT bitstreamIndexRvlFwd; /* base address of RVL-coded-scalefactor data (ESC
|
|
- 2) for forward decoding */
|
|
- INT bitstreamIndexRvlBwd; /* base address of RVL-coded-scalefactor data (ESC
|
|
- 2) for backward decoding */
|
|
- INT bitstreamIndexEsc; /* base address where RVLC-escapes start (ESC 2) */
|
|
-
|
|
- /* decoding trees */
|
|
- const UINT *pHuffTreeRvlCodewds;
|
|
- const UINT *pHuffTreeRvlcEscape;
|
|
-
|
|
- /* escape counters */
|
|
- UCHAR numDecodedEscapeWordsFwd; /* when decoding RVL-codes forward */
|
|
- UCHAR numDecodedEscapeWordsBwd; /* when decoding RVL-codes backward */
|
|
- UCHAR numDecodedEscapeWordsEsc; /* when decoding the escape-Words */
|
|
-
|
|
- SCHAR noise_used;
|
|
- SCHAR intensity_used;
|
|
- SCHAR sf_used;
|
|
-
|
|
- SHORT firstScf;
|
|
- SHORT lastScf;
|
|
- SHORT firstNrg;
|
|
- SHORT lastNrg;
|
|
- SHORT firstIs;
|
|
- SHORT lastIs;
|
|
-
|
|
- /* ------ RVLC error detection ------ */
|
|
- UINT errorLogRvlc; /* store RVLC errors */
|
|
- SHORT conceal_min; /* is set at backward decoding */
|
|
- SHORT conceal_max; /* is set at forward decoding */
|
|
- SHORT conceal_min_esc; /* is set at backward decoding */
|
|
- SHORT conceal_max_esc; /* is set at forward decoding */
|
|
-} CErRvlcInfo;
|
|
-
|
|
-typedef CErRvlcInfo RVLC_INFO; /* temp */
|
|
-
|
|
-#endif /* RVLC_INFO_H */
|
|
--- a/libAACdec/src/rvlcbit.cpp
|
|
+++ /dev/null
|
|
@@ -1,148 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s):
|
|
-
|
|
- Description:
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-/*!
|
|
- \file
|
|
- \brief RVLC bitstream reading
|
|
- \author Robert Weidner
|
|
-*/
|
|
-
|
|
-#include "rvlcbit.h"
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: rvlcReadBitFromBitstream
|
|
-
|
|
- description: This function returns a bit from the bitstream according to
|
|
-read direction. It is called very often, therefore it makes sense to inline it
|
|
-(runtime).
|
|
------------------------------------------------------------------------------------------------
|
|
- input: - bitstream
|
|
- - pPosition
|
|
- - readDirection
|
|
------------------------------------------------------------------------------------------------
|
|
- return: - bit from bitstream
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-UCHAR rvlcReadBitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|
- INT *pPosition, UCHAR readDirection) {
|
|
- UINT bit;
|
|
- INT readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pPosition;
|
|
-
|
|
- if (readBitOffset) {
|
|
- FDKpushBiDirectional(bs, readBitOffset);
|
|
- }
|
|
-
|
|
- if (readDirection == FWD) {
|
|
- bit = FDKreadBits(bs, 1);
|
|
-
|
|
- *pPosition += 1;
|
|
- } else {
|
|
- /* to be replaced with a brother function of FDKreadBits() */
|
|
- bit = FDKreadBits(bs, 1);
|
|
- FDKpushBack(bs, 2);
|
|
-
|
|
- *pPosition -= 1;
|
|
- }
|
|
-
|
|
- return (bit);
|
|
-}
|
|
--- a/libAACdec/src/rvlcbit.h
|
|
+++ /dev/null
|
|
@@ -1,111 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s): Robert Weidner (DSP Solutions)
|
|
-
|
|
- Description: RVLC Decoder: Bitstream reading
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-#ifndef RVLCBIT_H
|
|
-#define RVLCBIT_H
|
|
-
|
|
-#include "rvlc.h"
|
|
-
|
|
-UCHAR rvlcReadBitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|
- INT *pPosition, UCHAR readDirection);
|
|
-
|
|
-#endif /* RVLCBIT_H */
|
|
--- a/libAACdec/src/rvlcconceal.cpp
|
|
+++ /dev/null
|
|
@@ -1,787 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s):
|
|
-
|
|
- Description:
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-/*!
|
|
- \file
|
|
- \brief rvlc concealment
|
|
- \author Josef Hoepfl
|
|
-*/
|
|
-
|
|
-#include "rvlcconceal.h"
|
|
-
|
|
-#include "block.h"
|
|
-#include "rvlc.h"
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: calcRefValFwd
|
|
-
|
|
- description: The function determines the scalefactor which is closed to the
|
|
-scalefactorband conceal_min. The same is done for intensity data and noise
|
|
-energies.
|
|
------------------------------------------------------------------------------------------------
|
|
- output: - reference value scf
|
|
- - reference value internsity data
|
|
- - reference value noise energy
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void calcRefValFwd(CErRvlcInfo *pRvlc,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- int *refIsFwd, int *refNrgFwd, int *refScfFwd) {
|
|
- int band, bnds, group, startBand;
|
|
- int idIs, idNrg, idScf;
|
|
- int conceal_min, conceal_group_min;
|
|
- int MaximumScaleFactorBands;
|
|
-
|
|
- if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT)
|
|
- MaximumScaleFactorBands = 16;
|
|
- else
|
|
- MaximumScaleFactorBands = 64;
|
|
-
|
|
- conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands;
|
|
- conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands;
|
|
-
|
|
- /* calculate first reference value for approach in forward direction */
|
|
- idIs = idNrg = idScf = 1;
|
|
-
|
|
- /* set reference values */
|
|
- *refIsFwd = -SF_OFFSET;
|
|
- *refNrgFwd = pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain -
|
|
- SF_OFFSET - 90 - 256;
|
|
- *refScfFwd =
|
|
- pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET;
|
|
-
|
|
- startBand = conceal_min - 1;
|
|
- for (group = conceal_group_min; group >= 0; group--) {
|
|
- for (band = startBand; band >= 0; band--) {
|
|
- bnds = 16 * group + band;
|
|
- switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
|
|
- case ZERO_HCB:
|
|
- break;
|
|
- case INTENSITY_HCB:
|
|
- case INTENSITY_HCB2:
|
|
- if (idIs) {
|
|
- *refIsFwd =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- idIs = 0; /* reference value has been set */
|
|
- }
|
|
- break;
|
|
- case NOISE_HCB:
|
|
- if (idNrg) {
|
|
- *refNrgFwd =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- idNrg = 0; /* reference value has been set */
|
|
- }
|
|
- break;
|
|
- default:
|
|
- if (idScf) {
|
|
- *refScfFwd =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- idScf = 0; /* reference value has been set */
|
|
- }
|
|
- break;
|
|
- }
|
|
- }
|
|
- startBand = pRvlc->maxSfbTransmitted - 1;
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: calcRefValBwd
|
|
-
|
|
- description: The function determines the scalefactor which is closed to the
|
|
-scalefactorband conceal_max. The same is done for intensity data and noise
|
|
-energies.
|
|
------------------------------------------------------------------------------------------------
|
|
- output: - reference value scf
|
|
- - reference value internsity data
|
|
- - reference value noise energy
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-static void calcRefValBwd(CErRvlcInfo *pRvlc,
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- int *refIsBwd, int *refNrgBwd, int *refScfBwd) {
|
|
- int band, bnds, group, startBand;
|
|
- int idIs, idNrg, idScf;
|
|
- int conceal_max, conceal_group_max;
|
|
- int MaximumScaleFactorBands;
|
|
-
|
|
- if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT)
|
|
- MaximumScaleFactorBands = 16;
|
|
- else
|
|
- MaximumScaleFactorBands = 64;
|
|
-
|
|
- conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands;
|
|
- conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands;
|
|
-
|
|
- /* calculate first reference value for approach in backward direction */
|
|
- idIs = idNrg = idScf = 1;
|
|
-
|
|
- /* set reference values */
|
|
- *refIsBwd = pRvlc->dpcm_is_last_position - SF_OFFSET;
|
|
- *refNrgBwd = pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position -
|
|
- SF_OFFSET - 90 - 256 + pRvlc->dpcm_noise_nrg;
|
|
- *refScfBwd = pRvlc->rev_global_gain - SF_OFFSET;
|
|
-
|
|
- startBand = conceal_max + 1;
|
|
-
|
|
- /* if needed, re-set reference values */
|
|
- for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) {
|
|
- for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) {
|
|
- bnds = 16 * group + band;
|
|
- switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
|
|
- case ZERO_HCB:
|
|
- break;
|
|
- case INTENSITY_HCB:
|
|
- case INTENSITY_HCB2:
|
|
- if (idIs) {
|
|
- *refIsBwd =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
|
|
- idIs = 0; /* reference value has been set */
|
|
- }
|
|
- break;
|
|
- case NOISE_HCB:
|
|
- if (idNrg) {
|
|
- *refNrgBwd =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
|
|
- idNrg = 0; /* reference value has been set */
|
|
- }
|
|
- break;
|
|
- default:
|
|
- if (idScf) {
|
|
- *refScfBwd =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
|
|
- idScf = 0; /* reference value has been set */
|
|
- }
|
|
- break;
|
|
- }
|
|
- }
|
|
- startBand = 0;
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: BidirectionalEstimation_UseLowerScfOfCurrentFrame
|
|
-
|
|
- description: This approach by means of bidirectional estimation is generally
|
|
-performed when a single bit error has been detected, the bit error can be
|
|
-isolated between 'conceal_min' and 'conceal_max' and the 'sf_concealment' flag
|
|
-is not set. The sets of scalefactors decoded in forward and backward direction
|
|
-are compared with each other. The smaller scalefactor will be considered as the
|
|
-correct one respectively. The reconstruction of the scalefactors with this
|
|
-approach archieve good results in audio quality. The strategy must be applied to
|
|
-scalefactors, intensity data and noise energy seperately.
|
|
------------------------------------------------------------------------------------------------
|
|
- output: Concealed scalefactor, noise energy and intensity data between
|
|
-conceal_min and conceal_max
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-void BidirectionalEstimation_UseLowerScfOfCurrentFrame(
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
|
|
- CErRvlcInfo *pRvlc =
|
|
- &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
|
|
- int band, bnds, startBand, endBand, group;
|
|
- int conceal_min, conceal_max;
|
|
- int conceal_group_min, conceal_group_max;
|
|
- int MaximumScaleFactorBands;
|
|
-
|
|
- if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) {
|
|
- MaximumScaleFactorBands = 16;
|
|
- } else {
|
|
- MaximumScaleFactorBands = 64;
|
|
- }
|
|
-
|
|
- /* If an error was detected just in forward or backward direction, set the
|
|
- corresponding border for concealment to a appropriate scalefactor band. The
|
|
- border is set to first or last sfb respectively, because the error will
|
|
- possibly not follow directly after the corrupt bit but just after decoding
|
|
- some more (wrong) scalefactors. */
|
|
- if (pRvlc->conceal_min == CONCEAL_MIN_INIT) pRvlc->conceal_min = 0;
|
|
-
|
|
- if (pRvlc->conceal_max == CONCEAL_MAX_INIT)
|
|
- pRvlc->conceal_max =
|
|
- (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1;
|
|
-
|
|
- conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands;
|
|
- conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands;
|
|
- conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands;
|
|
- conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands;
|
|
-
|
|
- if (pRvlc->conceal_min == pRvlc->conceal_max) {
|
|
- int refIsFwd, refNrgFwd, refScfFwd;
|
|
- int refIsBwd, refNrgBwd, refScfBwd;
|
|
-
|
|
- bnds = pRvlc->conceal_min;
|
|
- calcRefValFwd(pRvlc, pAacDecoderChannelInfo, &refIsFwd, &refNrgFwd,
|
|
- &refScfFwd);
|
|
- calcRefValBwd(pRvlc, pAacDecoderChannelInfo, &refIsBwd, &refNrgBwd,
|
|
- &refScfBwd);
|
|
-
|
|
- switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
|
|
- case ZERO_HCB:
|
|
- break;
|
|
- case INTENSITY_HCB:
|
|
- case INTENSITY_HCB2:
|
|
- if (refIsFwd < refIsBwd)
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refIsFwd;
|
|
- else
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refIsBwd;
|
|
- break;
|
|
- case NOISE_HCB:
|
|
- if (refNrgFwd < refNrgBwd)
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refNrgFwd;
|
|
- else
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refNrgBwd;
|
|
- break;
|
|
- default:
|
|
- if (refScfFwd < refScfBwd)
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refScfFwd;
|
|
- else
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refScfBwd;
|
|
- break;
|
|
- }
|
|
- } else {
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfFwd[pRvlc->conceal_max] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[pRvlc->conceal_max];
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[pRvlc->conceal_min] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfFwd[pRvlc->conceal_min];
|
|
-
|
|
- /* consider the smaller of the forward and backward decoded value as the
|
|
- * correct one */
|
|
- startBand = conceal_min;
|
|
- if (conceal_group_min == conceal_group_max)
|
|
- endBand = conceal_max;
|
|
- else
|
|
- endBand = pRvlc->maxSfbTransmitted - 1;
|
|
-
|
|
- for (group = conceal_group_min; group <= conceal_group_max; group++) {
|
|
- for (band = startBand; band <= endBand; band++) {
|
|
- bnds = 16 * group + band;
|
|
- if (pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds] <
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds])
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- else
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
|
|
- }
|
|
- startBand = 0;
|
|
- if ((group + 1) == conceal_group_max) endBand = conceal_max;
|
|
- }
|
|
- }
|
|
-
|
|
- /* now copy all data to the output buffer which needs not to be concealed */
|
|
- if (conceal_group_min == 0)
|
|
- endBand = conceal_min;
|
|
- else
|
|
- endBand = pRvlc->maxSfbTransmitted;
|
|
- for (group = 0; group <= conceal_group_min; group++) {
|
|
- for (band = 0; band < endBand; band++) {
|
|
- bnds = 16 * group + band;
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- }
|
|
- if ((group + 1) == conceal_group_min) endBand = conceal_min;
|
|
- }
|
|
-
|
|
- startBand = conceal_max + 1;
|
|
- for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) {
|
|
- for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) {
|
|
- bnds = 16 * group + band;
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
|
|
- }
|
|
- startBand = 0;
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: BidirectionalEstimation_UseScfOfPrevFrameAsReference
|
|
-
|
|
- description: This approach by means of bidirectional estimation is generally
|
|
-performed when a single bit error has been detected, the bit error can be
|
|
-isolated between 'conceal_min' and 'conceal_max', the 'sf_concealment' flag is
|
|
-set and the previous frame has the same block type as the current frame. The
|
|
-scalefactor decoded in forward and backward direction and the scalefactor of the
|
|
-previous frame are compared with each other. The smaller scalefactor will be
|
|
-considered as the correct one. At this the codebook of the previous and current
|
|
-frame must be of the same set (scf, nrg, is) in each scalefactorband. Otherwise
|
|
-the scalefactor of the previous frame is not considered in the minimum
|
|
-calculation. The reconstruction of the scalefactors with this approach archieve
|
|
-good results in audio quality. The strategy must be applied to scalefactors,
|
|
-intensity data and noise energy seperately.
|
|
------------------------------------------------------------------------------------------------
|
|
- output: Concealed scalefactor, noise energy and intensity data between
|
|
-conceal_min and conceal_max
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-void BidirectionalEstimation_UseScfOfPrevFrameAsReference(
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
|
|
- CErRvlcInfo *pRvlc =
|
|
- &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
|
|
- int band, bnds, startBand, endBand, group;
|
|
- int conceal_min, conceal_max;
|
|
- int conceal_group_min, conceal_group_max;
|
|
- int MaximumScaleFactorBands;
|
|
- SHORT commonMin;
|
|
-
|
|
- if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) {
|
|
- MaximumScaleFactorBands = 16;
|
|
- } else {
|
|
- MaximumScaleFactorBands = 64;
|
|
- }
|
|
-
|
|
- /* If an error was detected just in forward or backward direction, set the
|
|
- corresponding border for concealment to a appropriate scalefactor band. The
|
|
- border is set to first or last sfb respectively, because the error will
|
|
- possibly not follow directly after the corrupt bit but just after decoding
|
|
- some more (wrong) scalefactors. */
|
|
- if (pRvlc->conceal_min == CONCEAL_MIN_INIT) pRvlc->conceal_min = 0;
|
|
-
|
|
- if (pRvlc->conceal_max == CONCEAL_MAX_INIT)
|
|
- pRvlc->conceal_max =
|
|
- (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1;
|
|
-
|
|
- conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands;
|
|
- conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands;
|
|
- conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands;
|
|
- conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands;
|
|
-
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfFwd[pRvlc->conceal_max] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[pRvlc->conceal_max];
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[pRvlc->conceal_min] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfFwd[pRvlc->conceal_min];
|
|
-
|
|
- /* consider the smaller of the forward and backward decoded value as the
|
|
- * correct one */
|
|
- startBand = conceal_min;
|
|
- if (conceal_group_min == conceal_group_max)
|
|
- endBand = conceal_max;
|
|
- else
|
|
- endBand = pRvlc->maxSfbTransmitted - 1;
|
|
-
|
|
- for (group = conceal_group_min; group <= conceal_group_max; group++) {
|
|
- for (band = startBand; band <= endBand; band++) {
|
|
- bnds = 16 * group + band;
|
|
- switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
|
|
- case ZERO_HCB:
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0;
|
|
- break;
|
|
-
|
|
- case INTENSITY_HCB:
|
|
- case INTENSITY_HCB2:
|
|
- if ((pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB) ||
|
|
- (pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB2)) {
|
|
- commonMin = fMin(
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[bnds]);
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousScaleFactor[bnds]);
|
|
- } else {
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin(
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[bnds]);
|
|
- }
|
|
- break;
|
|
-
|
|
- case NOISE_HCB:
|
|
- if (pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] == NOISE_HCB) {
|
|
- commonMin = fMin(
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[bnds]);
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousScaleFactor[bnds]);
|
|
- } else {
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin(
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[bnds]);
|
|
- }
|
|
- break;
|
|
-
|
|
- default:
|
|
- if ((pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] != ZERO_HCB) &&
|
|
- (pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] != NOISE_HCB) &&
|
|
- (pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB) &&
|
|
- (pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB2)) {
|
|
- commonMin = fMin(
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[bnds]);
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousScaleFactor[bnds]);
|
|
- } else {
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin(
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[bnds]);
|
|
- }
|
|
- break;
|
|
- }
|
|
- }
|
|
- startBand = 0;
|
|
- if ((group + 1) == conceal_group_max) endBand = conceal_max;
|
|
- }
|
|
-
|
|
- /* now copy all data to the output buffer which needs not to be concealed */
|
|
- if (conceal_group_min == 0)
|
|
- endBand = conceal_min;
|
|
- else
|
|
- endBand = pRvlc->maxSfbTransmitted;
|
|
- for (group = 0; group <= conceal_group_min; group++) {
|
|
- for (band = 0; band < endBand; band++) {
|
|
- bnds = 16 * group + band;
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- }
|
|
- if ((group + 1) == conceal_group_min) endBand = conceal_min;
|
|
- }
|
|
-
|
|
- startBand = conceal_max + 1;
|
|
- for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) {
|
|
- for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) {
|
|
- bnds = 16 * group + band;
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
|
|
- }
|
|
- startBand = 0;
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- function: StatisticalEstimation
|
|
-
|
|
- description: This approach by means of statistical estimation is generally
|
|
-performed when both the start value and the end value are different and no
|
|
-further errors have been detected. Considering the forward and backward decoded
|
|
-scalefactors, the set with the lower scalefactors in sum will be considered as
|
|
-the correct one. The scalefactors are differentially encoded. Normally it would
|
|
-reach to compare one pair of the forward and backward decoded scalefactors to
|
|
-specify the lower set. But having detected no further errors does not
|
|
-necessarily mean the absence of errors. Therefore all scalefactors decoded in
|
|
-forward and backward direction are summed up seperately. The set with the lower
|
|
-sum will be used. The strategy must be applied to scalefactors, intensity data
|
|
-and noise energy seperately.
|
|
------------------------------------------------------------------------------------------------
|
|
- output: Concealed scalefactor, noise energy and intensity data
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-void StatisticalEstimation(CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
|
|
- CErRvlcInfo *pRvlc =
|
|
- &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
|
|
- int band, bnds, group;
|
|
- int sumIsFwd, sumIsBwd; /* sum of intensity data forward/backward */
|
|
- int sumNrgFwd, sumNrgBwd; /* sum of noise energy data forward/backward */
|
|
- int sumScfFwd, sumScfBwd; /* sum of scalefactor data forward/backward */
|
|
- int useIsFwd, useNrgFwd, useScfFwd; /* the flags signals the elements which
|
|
- are used for the final result */
|
|
-
|
|
- sumIsFwd = sumIsBwd = sumNrgFwd = sumNrgBwd = sumScfFwd = sumScfBwd = 0;
|
|
- useIsFwd = useNrgFwd = useScfFwd = 0;
|
|
-
|
|
- /* calculate sum of each group (scf,nrg,is) of forward and backward direction
|
|
- */
|
|
- for (group = 0; group < pRvlc->numWindowGroups; group++) {
|
|
- for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
|
|
- bnds = 16 * group + band;
|
|
- switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
|
|
- case ZERO_HCB:
|
|
- break;
|
|
-
|
|
- case INTENSITY_HCB:
|
|
- case INTENSITY_HCB2:
|
|
- sumIsFwd +=
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- sumIsBwd +=
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
|
|
- break;
|
|
-
|
|
- case NOISE_HCB:
|
|
- sumNrgFwd +=
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- sumNrgBwd +=
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
|
|
- break;
|
|
-
|
|
- default:
|
|
- sumScfFwd +=
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- sumScfBwd +=
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
|
|
- break;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- /* find for each group (scf,nrg,is) the correct direction */
|
|
- if (sumIsFwd < sumIsBwd) useIsFwd = 1;
|
|
-
|
|
- if (sumNrgFwd < sumNrgBwd) useNrgFwd = 1;
|
|
-
|
|
- if (sumScfFwd < sumScfBwd) useScfFwd = 1;
|
|
-
|
|
- /* conceal each group (scf,nrg,is) */
|
|
- for (group = 0; group < pRvlc->numWindowGroups; group++) {
|
|
- for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
|
|
- bnds = 16 * group + band;
|
|
- switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
|
|
- case ZERO_HCB:
|
|
- break;
|
|
-
|
|
- case INTENSITY_HCB:
|
|
- case INTENSITY_HCB2:
|
|
- if (useIsFwd)
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- else
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
|
|
- break;
|
|
-
|
|
- case NOISE_HCB:
|
|
- if (useNrgFwd)
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- else
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
|
|
- break;
|
|
-
|
|
- default:
|
|
- if (useScfFwd)
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
|
|
- else
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
|
|
- break;
|
|
- }
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-/*---------------------------------------------------------------------------------------------
|
|
- description: Approach by means of predictive interpolation
|
|
- This approach by means of predictive estimation is generally
|
|
-performed when the error cannot be isolated between 'conceal_min' and
|
|
-'conceal_max', the 'sf_concealment' flag is set and the previous frame has the
|
|
-same block type as the current frame. Check for each scalefactorband if the same
|
|
-type of data (scalefactor, internsity data, noise energies) is transmitted. If
|
|
-so use the scalefactor (intensity data, noise energy) in the current frame.
|
|
-Otherwise set the scalefactor (intensity data, noise energy) for this
|
|
-scalefactorband to zero.
|
|
------------------------------------------------------------------------------------------------
|
|
- output: Concealed scalefactor, noise energy and intensity data
|
|
------------------------------------------------------------------------------------------------
|
|
- return: -
|
|
---------------------------------------------------------------------------------------------
|
|
-*/
|
|
-
|
|
-void PredictiveInterpolation(
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
|
|
- CErRvlcInfo *pRvlc =
|
|
- &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
|
|
- int band, bnds, group;
|
|
- SHORT commonMin;
|
|
-
|
|
- for (group = 0; group < pRvlc->numWindowGroups; group++) {
|
|
- for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
|
|
- bnds = 16 * group + band;
|
|
- switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
|
|
- case ZERO_HCB:
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0;
|
|
- break;
|
|
-
|
|
- case INTENSITY_HCB:
|
|
- case INTENSITY_HCB2:
|
|
- if ((pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB) ||
|
|
- (pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB2)) {
|
|
- commonMin = fMin(
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[bnds]);
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousScaleFactor[bnds]);
|
|
- } else {
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = -110;
|
|
- }
|
|
- break;
|
|
-
|
|
- case NOISE_HCB:
|
|
- if (pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] == NOISE_HCB) {
|
|
- commonMin = fMin(
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[bnds]);
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousScaleFactor[bnds]);
|
|
- } else {
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = -110;
|
|
- }
|
|
- break;
|
|
-
|
|
- default:
|
|
- if ((pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] != ZERO_HCB) &&
|
|
- (pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] != NOISE_HCB) &&
|
|
- (pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB) &&
|
|
- (pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB2)) {
|
|
- commonMin = fMin(
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
|
|
- pAacDecoderChannelInfo->pComData->overlay.aac
|
|
- .aRvlcScfBwd[bnds]);
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
|
|
- fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
|
|
- .aRvlcPreviousScaleFactor[bnds]);
|
|
- } else {
|
|
- pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0;
|
|
- }
|
|
- break;
|
|
- }
|
|
- }
|
|
- }
|
|
-}
|
|
--- a/libAACdec/src/rvlcconceal.h
|
|
+++ /dev/null
|
|
@@ -1,127 +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
|
|
------------------------------------------------------------------------------ */
|
|
-
|
|
-/**************************** AAC decoder library ******************************
|
|
-
|
|
- Author(s):
|
|
-
|
|
- Description:
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-/*!
|
|
- \file
|
|
- \brief rvlc concealment
|
|
- \author Josef Hoepfl
|
|
-*/
|
|
-
|
|
-#ifndef RVLCCONCEAL_H
|
|
-#define RVLCCONCEAL_H
|
|
-
|
|
-#include "rvlc.h"
|
|
-
|
|
-void BidirectionalEstimation_UseLowerScfOfCurrentFrame(
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo);
|
|
-
|
|
-void BidirectionalEstimation_UseScfOfPrevFrameAsReference(
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo);
|
|
-
|
|
-void StatisticalEstimation(CAacDecoderChannelInfo *pAacDecoderChannelInfo);
|
|
-
|
|
-void PredictiveInterpolation(
|
|
- CAacDecoderChannelInfo *pAacDecoderChannelInfo,
|
|
- CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo);
|
|
-
|
|
-#endif /* RVLCCONCEAL_H */
|
|
--- a/libAACdec/src/usacdec_lpd.cpp
|
|
+++ b/libAACdec/src/usacdec_lpd.cpp
|
|
@@ -111,8 +111,6 @@ amm-info@iis.fraunhofer.de
|
|
#include "usacdec_acelp.h"
|
|
#include "overlapadd.h"
|
|
|
|
-#include "conceal.h"
|
|
-
|
|
#include "block.h"
|
|
|
|
#define SF_PITCH_TRACK 6
|
|
@@ -1210,8 +1208,7 @@ AAC_DECODER_ERROR CLpdChannelStream_Read
|
|
: &lg_table_ccfl[1][lg_table_offset];
|
|
int last_lpc_lost = pAacDecoderStaticChannelInfo->last_lpc_lost;
|
|
|
|
- int last_frame_ok = CConcealment_GetLastFrameOk(
|
|
- &pAacDecoderStaticChannelInfo->concealmentInfo, 1);
|
|
+ int last_frame_ok = 1;
|
|
|
|
INT i_offset;
|
|
UINT samplingRate;
|
|
@@ -1392,13 +1389,7 @@ AAC_DECODER_ERROR CLpdChannelStream_Read
|
|
}
|
|
}
|
|
|
|
- if (!CConcealment_GetLastFrameOk(
|
|
- &pAacDecoderStaticChannelInfo->concealmentInfo, 1)) {
|
|
- E_LPC_f_lsp_a_conversion(
|
|
- pAacDecoderChannelInfo->data.usac.lsp_coeff[0],
|
|
- pAacDecoderChannelInfo->data.usac.lp_coeff[0],
|
|
- &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0]);
|
|
- } else if (pAacDecoderStaticChannelInfo->last_lpd_mode != 0) {
|
|
+ if (pAacDecoderStaticChannelInfo->last_lpd_mode != 0) {
|
|
if (pAacDecoderStaticChannelInfo->last_lpd_mode == 255) {
|
|
/* We need it for TCX decoding or ACELP excitation update */
|
|
E_LPC_f_lsp_a_conversion(
|
|
@@ -1426,9 +1417,7 @@ AAC_DECODER_ERROR CLpdChannelStream_Read
|
|
FD_SHORT;
|
|
pAacDecoderChannelInfo->data.usac.lpd_mode_last = 255;
|
|
|
|
- if ((pAacDecoderStaticChannelInfo->last_core_mode != FD_SHORT) &&
|
|
- CConcealment_GetLastFrameOk(
|
|
- &pAacDecoderStaticChannelInfo->concealmentInfo, 1)) {
|
|
+ if ((pAacDecoderStaticChannelInfo->last_core_mode != FD_SHORT)) {
|
|
/* USAC Conformance document:
|
|
short_fac_flag shall be encoded with a value of 1 if the
|
|
window_sequence of the previous frame was 2 (EIGHT_SHORT_SEQUENCE).
|
|
@@ -1604,8 +1593,7 @@ AAC_DECODER_ERROR CLpd_RenderTimeSignal(
|
|
return AAC_DEC_UNKNOWN;
|
|
}
|
|
|
|
- last_frame_lost = !CConcealment_GetLastFrameOk(
|
|
- &pAacDecoderStaticChannelInfo->concealmentInfo, 0);
|
|
+ last_frame_lost = 0;
|
|
|
|
/* Maintain LPD mode from previous frame */
|
|
if ((pAacDecoderStaticChannelInfo->last_core_mode == FD_LONG) ||
|