Home | History | Annotate | Download | only in src
      1 /* -----------------------------------------------------------------------------
      2 Software License for The Fraunhofer FDK AAC Codec Library for Android
      3 
      4  Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Frderung der angewandten
      5 Forschung e.V. All rights reserved.
      6 
      7  1.    INTRODUCTION
      8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
      9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
     10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
     11 a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
     14 general perceptual audio codecs. AAC-ELD is considered the best-performing
     15 full-bandwidth communications codec by independent studies and is widely
     16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
     17 specifications.
     18 
     19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
     20 those of Fraunhofer) may be obtained through Via Licensing
     21 (www.vialicensing.com) or through the respective patent owners individually for
     22 the purpose of encoding or decoding bit streams in products that are compliant
     23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
     24 Android devices already license these patent claims through Via Licensing or
     25 directly from the patent owners, and therefore FDK AAC Codec software may
     26 already be covered under those patent licenses when it is used for those
     27 licensed purposes only.
     28 
     29 Commercially-licensed AAC software libraries, including floating-point versions
     30 with enhanced sound quality, are also available from Fraunhofer. Users are
     31 encouraged to check the Fraunhofer website for additional applications
     32 information and documentation.
     33 
     34 2.    COPYRIGHT LICENSE
     35 
     36 Redistribution and use in source and binary forms, with or without modification,
     37 are permitted without payment of copyright license fees provided that you
     38 satisfy the following conditions:
     39 
     40 You must retain the complete text of this software license in redistributions of
     41 the FDK AAC Codec or your modifications thereto in source code form.
     42 
     43 You must retain the complete text of this software license in the documentation
     44 and/or other materials provided with redistributions of the FDK AAC Codec or
     45 your modifications thereto in binary form. You must make available free of
     46 charge copies of the complete source code of the FDK AAC Codec and your
     47 modifications thereto to recipients of copies in binary form.
     48 
     49 The name of Fraunhofer may not be used to endorse or promote products derived
     50 from this library without prior written permission.
     51 
     52 You may not charge copyright license fees for anyone to use, copy or distribute
     53 the FDK AAC Codec software or your modifications thereto.
     54 
     55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
     56 that you changed the software and the date of any change. For modified versions
     57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
     58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
     59 AAC Codec Library for Android."
     60 
     61 3.    NO PATENT LICENSE
     62 
     63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
     64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
     65 Fraunhofer provides no warranty of patent non-infringement with respect to this
     66 software.
     67 
     68 You may use this FDK AAC Codec software or modifications thereto only for
     69 purposes that are authorized by appropriate patent licenses.
     70 
     71 4.    DISCLAIMER
     72 
     73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
     74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
     75 including but not limited to the implied warranties of merchantability and
     76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
     78 or consequential damages, including but not limited to procurement of substitute
     79 goods or services; loss of use, data, or profits, or business interruption,
     80 however caused and on any theory of liability, whether in contract, strict
     81 liability, or tort (including negligence), arising in any way out of the use of
     82 this software, even if advised of the possibility of such damage.
     83 
     84 5.    CONTACT INFORMATION
     85 
     86 Fraunhofer Institute for Integrated Circuits IIS
     87 Attention: Audio and Multimedia Departments - FDK AAC LL
     88 Am Wolfsmantel 33
     89 91058 Erlangen, Germany
     90 
     91 www.iis.fraunhofer.de/amm
     92 amm-info (at) iis.fraunhofer.de
     93 ----------------------------------------------------------------------------- */
     94 
     95 /******************* Library for basic calculation routines ********************
     96 
     97    Author(s):   Markus Lohwasser
     98 
     99    Description: FDK Tools Decorrelator
    100 
    101 *******************************************************************************/
    102 
    103 #include "FDK_decorrelate.h"
    104 
    105 #define PC_NUM_BANDS (8)
    106 #define PC_NUM_HYB_BANDS (PC_NUM_BANDS - 3 + 10)
    107 
    108 #define DUCK_ALPHA (0.8f)
    109 #define DUCK_GAMMA (1.5f)
    110 #define ABS_THR (1e-9f * 32768 * 32768)
    111 #define ABS_THR_FDK ((FIXP_DBL)1)
    112 
    113 #define DECORR_ZERO_PADDING 0
    114 
    115 #define DECORR_FILTER_ORDER_BAND_0_MPS (20)
    116 #define DECORR_FILTER_ORDER_BAND_1_MPS (15)
    117 #define DECORR_FILTER_ORDER_BAND_2_MPS (6)
    118 #define DECORR_FILTER_ORDER_BAND_3_MPS (3)
    119 
    120 #define DECORR_FILTER_ORDER_BAND_0_USAC (10)
    121 #define DECORR_FILTER_ORDER_BAND_1_USAC (8)
    122 #define DECORR_FILTER_ORDER_BAND_2_USAC (3)
    123 #define DECORR_FILTER_ORDER_BAND_3_USAC (2)
    124 
    125 #define DECORR_FILTER_ORDER_BAND_0_LD (0)
    126 #define DECORR_FILTER_ORDER_BAND_1_LD (DECORR_FILTER_ORDER_BAND_1_MPS)
    127 #define DECORR_FILTER_ORDER_BAND_2_LD (DECORR_FILTER_ORDER_BAND_2_MPS)
    128 #define DECORR_FILTER_ORDER_BAND_3_LD (DECORR_FILTER_ORDER_BAND_3_MPS)
    129 
    130 #define MAX_DECORR_SEED_MPS \
    131   (5) /* 4 is worst case for 7272 mode for low power */
    132       /* 5 is worst case for 7271 and 7272 mode for high quality */
    133 #define MAX_DECORR_SEED_USAC (1)
    134 #define MAX_DECORR_SEED_LD (4)
    135 
    136 #define DECORR_FILTER_ORDER_PS (12)
    137 #define NUM_DECORR_CONFIGS \
    138   (3) /* different configs defined by bsDecorrConfig bitstream field */
    139 
    140 /* REV_bandOffset_... tables map (hybrid) bands to the corresponding reverb
    141    bands. Within each reverb band the same processing is applied. Instead of QMF
    142    split frequencies the corresponding hybrid band offsets are stored directly
    143  */
    144 static const UCHAR REV_bandOffset_MPS_HQ[NUM_DECORR_CONFIGS][(4)] = {
    145     {8, 21, 30, 71}, {8, 56, 71, 71}, {0, 21, 71, 71}};
    146 /* REV_bandOffset_USAC[] are equivalent to REV_bandOffset_MPS_HQ */
    147 static const UCHAR REV_bandOffset_PS_HQ[(4)] = {30, 42, 71, 71};
    148 static const UCHAR REV_bandOffset_PS_LP[(4)] = {14, 42, 71, 71};
    149 static const UCHAR REV_bandOffset_LD[NUM_DECORR_CONFIGS][(4)] = {
    150     {0, 14, 23, 64}, {0, 49, 64, 64}, {0, 14, 64, 64}};
    151 
    152 /* REV_delay_... tables define the number of delay elements within each reverb
    153  * band */
    154 /* REV_filterOrder_... tables define the filter order within each reverb band */
    155 static const UCHAR REV_delay_MPS[(4)] = {8, 7, 2, 1};
    156 static const SCHAR REV_filterOrder_MPS[(4)] = {
    157     DECORR_FILTER_ORDER_BAND_0_MPS, DECORR_FILTER_ORDER_BAND_1_MPS,
    158     DECORR_FILTER_ORDER_BAND_2_MPS, DECORR_FILTER_ORDER_BAND_3_MPS};
    159 static const UCHAR REV_delay_PS_HQ[(4)] = {2, 14, 1, 0};
    160 static const UCHAR REV_delay_PS_LP[(4)] = {8, 14, 1, 0};
    161 static const SCHAR REV_filterOrder_PS[(4)] = {DECORR_FILTER_ORDER_PS, -1, -1,
    162                                               -1};
    163 static const UCHAR REV_delay_USAC[(4)] = {11, 10, 5, 2};
    164 static const SCHAR REV_filterOrder_USAC[(4)] = {
    165     DECORR_FILTER_ORDER_BAND_0_USAC, DECORR_FILTER_ORDER_BAND_1_USAC,
    166     DECORR_FILTER_ORDER_BAND_2_USAC, DECORR_FILTER_ORDER_BAND_3_USAC};
    167 
    168 /* REV_filtType_... tables define the type of processing (filtering with
    169    different properties or pure delay) done in each reverb band. This is mapped
    170    to specialized routines. */
    171 static const REVBAND_FILT_TYPE REV_filtType_MPS[(4)] = {
    172     COMMON_REAL, COMMON_REAL, COMMON_REAL, COMMON_REAL};
    173 
    174 static const REVBAND_FILT_TYPE REV_filtType_PS[(4)] = {INDEP_CPLX_PS, DELAY,
    175                                                        DELAY, NOT_EXIST};
    176 
    177 /* initialization values of ring buffer offsets for the 3 concatenated allpass
    178  * filters (PS type decorrelator). */
    179 static const UCHAR stateBufferOffsetInit[(3)] = {0, 6, 14};
    180 
    181 static const REVBAND_FILT_TYPE REV_filtType_LD[(4)] = {
    182     NOT_EXIST, COMMON_REAL, COMMON_REAL, COMMON_REAL};
    183 
    184 /*** mapping of hybrid bands to processing (/parameter?) bands ***/
    185 /* table for PS decorr running in legacy PS decoder. */
    186 static const UCHAR kernels_20_to_71_PS[(71) + 1] = {
    187     0,  0,  1,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 14,
    188     15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18,
    189     18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    190     19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19};
    191 
    192 /*** mapping of processing (/parameter?) bands to hybrid bands ***/
    193 /* table for PS decorr running in legacy PS decoder. */
    194 static const UCHAR kernels_20_to_71_offset_PS[(20) + 1] = {
    195     0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 21, 25, 30, 42, 71};
    196 
    197 static const UCHAR kernels_28_to_71[(71) + 1] = {
    198     0,  0,  1,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,
    199     16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23,
    200     23, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26,
    201     26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27};
    202 
    203 static const UCHAR kernels_28_to_71_offset[(28) + 1] = {
    204     0,  2,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16,
    205     17, 18, 19, 21, 23, 25, 27, 30, 33, 37, 42, 48, 55, 71};
    206 
    207 /* LD-MPS defined in SAOC standart (mapping qmf -> param bands)*/
    208 static const UCHAR kernels_23_to_64[(64) + 1] = {
    209     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 12, 13, 13, 14,
    210     14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,
    211     19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22,
    212     22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
    213 };
    214 
    215 static const UCHAR kernels_23_to_64_offset[(23) + 1] = {
    216     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11,
    217     12, 14, 16, 18, 20, 23, 26, 30, 35, 41, 48, 64};
    218 
    219 static inline int SpatialDecGetProcessingBand(int hybridBand,
    220                                               const UCHAR *tab) {
    221   return tab[hybridBand];
    222 }
    223 
    224 /* helper inline function */
    225 static inline int SpatialDecGetQmfBand(int paramBand, const UCHAR *tab) {
    226   return (int)tab[paramBand];
    227 }
    228 
    229 #define DUCKER_MAX_NRG_SCALE (24)
    230 #define DUCKER_HEADROOM_BITS (3)
    231 
    232 #define FILTER_SF (2)
    233 
    234 #ifdef ARCH_PREFER_MULT_32x32
    235 #define FIXP_DUCK_GAIN FIXP_DBL
    236 #define FX_DBL2FX_DUCK_GAIN
    237 #define FL2FXCONST_DUCK FL2FXCONST_DBL
    238 #else
    239 #define FIXP_DUCK_GAIN FIXP_SGL
    240 #define FX_DBL2FX_DUCK_GAIN FX_DBL2FX_SGL
    241 #define FL2FXCONST_DUCK FL2FXCONST_SGL
    242 #endif
    243 #define PS_DUCK_PEAK_DECAY_FACTOR (0.765928338364649f)
    244 #define PS_DUCK_FILTER_COEFF (0.25f)
    245 #define DUCK_ALPHA_FDK FL2FXCONST_DUCK(DUCK_ALPHA)
    246 #define DUCK_ONE_MINUS_ALPHA_X4_FDK FL2FXCONST_DUCK(4.0f * (1.0f - DUCK_ALPHA))
    247 #define DUCK_GAMMA_FDK FL2FXCONST_DUCK(DUCK_GAMMA / 2)
    248 #define PS_DUCK_PEAK_DECAY_FACTOR_FDK FL2FXCONST_DUCK(PS_DUCK_PEAK_DECAY_FACTOR)
    249 #define PS_DUCK_FILTER_COEFF_FDK FL2FXCONST_DUCK(PS_DUCK_FILTER_COEFF)
    250 RAM_ALIGN
    251 const FIXP_STP DecorrPsCoeffsCplx[][4] = {
    252     {STCP(0x5d6940eb, 0x5783153e), STCP(0xadcd41a8, 0x0e0373ed),
    253      STCP(0xbad41f3e, 0x14fba045), STCP(0xc1eb6694, 0x0883227d)},
    254     {STCP(0x5d6940eb, 0xa87ceac2), STCP(0xadcd41a8, 0xf1fc8c13),
    255      STCP(0xbad41f3e, 0xeb045fbb), STCP(0xc1eb6694, 0xf77cdd83)},
    256     {STCP(0xaec24162, 0x62e9d75b), STCP(0xb7169316, 0x28751048),
    257      STCP(0xd224c0cc, 0x37e05050), STCP(0xc680864f, 0x18e88cba)},
    258     {STCP(0xaec24162, 0x9d1628a5), STCP(0xb7169316, 0xd78aefb8),
    259      STCP(0xd224c0cc, 0xc81fafb0), STCP(0xc680864f, 0xe7177346)},
    260     {STCP(0x98012341, 0x4aa00ed1), STCP(0xc89ca1b2, 0xc1ab6bff),
    261      STCP(0xf8ea394e, 0xb8106bf4), STCP(0xcf542d73, 0xd888b99b)},
    262     {STCP(0x43b137b3, 0x6ca2ca40), STCP(0xe0649cc4, 0xb2d69cca),
    263      STCP(0x22130c21, 0xc0405382), STCP(0xdbbf8fba, 0xcce3c7cc)},
    264     {STCP(0x28fc4d71, 0x86bd3b87), STCP(0x09ccfeb9, 0xad319baf),
    265      STCP(0x46e51f02, 0xf1e5ea55), STCP(0xf30d5e34, 0xc2b0e335)},
    266     {STCP(0xc798f756, 0x72e73c7d), STCP(0x3b6c3c1e, 0xc580dc72),
    267      STCP(0x2828a6ba, 0x3c1a14fb), STCP(0x14b733bb, 0xc4dcaae1)},
    268     {STCP(0x46dcadd3, 0x956795c7), STCP(0x52f32fae, 0xf78048cd),
    269      STCP(0xd7d75946, 0x3c1a14fb), STCP(0x306017cb, 0xd82c0a75)},
    270     {STCP(0xabe197de, 0x607a675e), STCP(0x460cef6e, 0x2d3b264e),
    271      STCP(0xb91ae0fe, 0xf1e5ea55), STCP(0x3e03e5e0, 0xf706590e)},
    272     {STCP(0xb1b4f509, 0x9abcaf5f), STCP(0xfeb0b4be, 0x535fb8ba),
    273      STCP(0x1ba96f8e, 0xbd37e6d8), STCP(0x30f6dbbb, 0x271a0743)},
    274     {STCP(0xce75b52a, 0x89f9be61), STCP(0xb26e4dda, 0x101054c5),
    275      STCP(0x1a475d2e, 0x3f714b19), STCP(0xf491f154, 0x3a6baf46)},
    276     {STCP(0xee8fdfcb, 0x813181fa), STCP(0xe11e1a00, 0xbb9a6039),
    277      STCP(0xc3e582f5, 0xe71ab533), STCP(0xc9eb35e2, 0x0ffd212a)},
    278     {STCP(0x0fd7d92f, 0x80fbf975), STCP(0x38adccbc, 0xd571bbf4),
    279      STCP(0x38c3aefc, 0xe87cc794), STCP(0xdafe8c3d, 0xd9b16100)},
    280     {STCP(0x300d9e10, 0x895cc359), STCP(0x32b9843e, 0x2b52adcc),
    281      STCP(0xe9ded9f4, 0x356ce0ed), STCP(0x0fdd5ca3, 0xd072932e)},
    282     {STCP(0x4d03b4f8, 0x99c2dec3), STCP(0xe2bc8d94, 0x3744e195),
    283      STCP(0xeb40ec55, 0xcde9ed22), STCP(0x2e67e231, 0xf893470b)},
    284     {STCP(0x64c4deb3, 0xb112790f), STCP(0xc7b32682, 0xf099172d),
    285      STCP(0x2ebf44cf, 0x135d014a), STCP(0x1a2bacd5, 0x23334254)},
    286     {STCP(0x75b5f9aa, 0xcdb81e14), STCP(0x028d9bb1, 0xc9dc45b9),
    287      STCP(0xd497893f, 0x11faeee9), STCP(0xee40ff71, 0x24a91b85)},
    288     {STCP(0x7eb1cd81, 0xedc3feec), STCP(0x31491897, 0xf765f6d8),
    289      STCP(0x1098dc89, 0xd7ee574e), STCP(0xda6b816d, 0x011f35cf)},
    290     {STCP(0x7f1cde01, 0x0f0b7727), STCP(0x118ce49d, 0x2a5ecda4),
    291      STCP(0x0f36ca28, 0x24badaa3), STCP(0xef2908a4, 0xe1ee3743)},
    292     {STCP(0x76efee25, 0x2f4e8c3a), STCP(0xdde3be2a, 0x17f92215),
    293      STCP(0xde9bf36c, 0xf22b4839), STCP(0x1128fc0c, 0xe5c95f5a)},
    294     {STCP(0x66b87d65, 0x4c5ede42), STCP(0xe43f351a, 0xe6bf22dc),
    295      STCP(0x1e0d3e85, 0xf38d5a9a), STCP(0x1c0f44a3, 0x02c92fe3)},
    296     {STCP(0x4f8f36b7, 0x6445680f), STCP(0x10867ea2, 0xe3072740),
    297      STCP(0xf4ef6cfa, 0x1ab67076), STCP(0x09562a8a, 0x1742bb8b)},
    298     {STCP(0x3304f6ec, 0x7564812a), STCP(0x1be4f1a8, 0x0894d75a),
    299      STCP(0xf6517f5b, 0xe8a05d98), STCP(0xf1bb0053, 0x10a78853)},
    300     {STCP(0x1307b2c5, 0x7e93d532), STCP(0xfe098e27, 0x18f02a58),
    301      STCP(0x1408d459, 0x084c6e44), STCP(0xedafe5bd, 0xfbc15b2e)},
    302     {STCP(0xf1c111cd, 0x7f346c97), STCP(0xeb5ca6a0, 0x02efee93),
    303      STCP(0xef4df9b6, 0x06ea5be4), STCP(0xfc149289, 0xf0d53ce4)},
    304     {STCP(0xd1710001, 0x773b6beb), STCP(0xfa1aeb8c, 0xf06655ff),
    305      STCP(0x05884983, 0xf2a4c7c5), STCP(0x094f13df, 0xf79c01bf)},
    306     {STCP(0xb446be0b, 0x6732cfca), STCP(0x0a743752, 0xf9220dfa),
    307      STCP(0x04263722, 0x0a046a2c), STCP(0x08ced80b, 0x0347e9c2)},
    308     {STCP(0x9c3b1202, 0x503018a5), STCP(0x05fcf01a, 0x05cd8529),
    309      STCP(0xf95263e2, 0xfd3bdb3f), STCP(0x00c68cf9, 0x0637cb7f)},
    310     {STCP(0x8aee2710, 0x33c187ec), STCP(0xfdd253f8, 0x038e09b9),
    311      STCP(0x0356ce0f, 0xfe9ded9f), STCP(0xfd6c3054, 0x01c8060a)}};
    312 
    313 const FIXP_DECORR DecorrNumeratorReal0_USAC
    314     [MAX_DECORR_SEED_USAC][DECORR_FILTER_ORDER_BAND_0_USAC + 1] = {
    315         {DECORR(0x05bf4880), DECORR(0x08321c00), DECORR(0xe9315ee0),
    316          DECORR(0x07d9dd20), DECORR(0x02224994), DECORR(0x0009d200),
    317          DECORR(0xf8a29358), DECORR(0xf4e310d0), DECORR(0xef901fc0),
    318          DECORR(0xebda0460), DECORR(0x40000000)}};
    319 
    320 const FIXP_DECORR DecorrNumeratorReal1_USAC
    321     [MAX_DECORR_SEED_USAC][DECORR_FILTER_ORDER_BAND_1_USAC + 1] = {
    322         {DECORR(0xf82f8378), DECORR(0xfef588c2), DECORR(0x02eddbd8),
    323          DECORR(0x041c2450), DECORR(0xf7edcd60), DECORR(0x07e29310),
    324          DECORR(0xfa4ece48), DECORR(0xed9f8a20), DECORR(0x40000000)}};
    325 
    326 /* identical to MPS coeffs for reverb band 3: DecorrNumeratorReal3[0] */
    327 const FIXP_DECORR
    328     DecorrNumeratorReal2_USAC[MAX_DECORR_SEED_USAC]
    329                              [DECORR_FILTER_ORDER_BAND_2_USAC + 1] = {
    330                                  {DECORR(0x0248e8a8), DECORR(0xfde95838),
    331                                   DECORR(0x084823c0), DECORR(0x40000000)}};
    332 
    333 const FIXP_DECORR
    334     DecorrNumeratorReal3_USAC[MAX_DECORR_SEED_USAC]
    335                              [DECORR_FILTER_ORDER_BAND_3_USAC + 1] = {
    336                                  {DECORR(0xff2b020c), DECORR(0x02393830),
    337                                   DECORR(0x40000000)}};
    338 
    339 /* const FIXP_DECORR DecorrNumeratorReal0_LD[MAX_DECORR_SEED_LD][] does not
    340  * exist */
    341 
    342 RAM_ALIGN
    343 const FIXP_DECORR DecorrNumeratorReal1_LD[MAX_DECORR_SEED_LD]
    344                                          [DECORR_FILTER_ORDER_BAND_1_LD + 1] = {
    345                                              {
    346                                                  DECORR(0xf310cb29),
    347                                                  DECORR(0x1932d745),
    348                                                  DECORR(0x0cc2d917),
    349                                                  DECORR(0xddde064e),
    350                                                  DECORR(0xf234a626),
    351                                                  DECORR(0x198551a6),
    352                                                  DECORR(0x17141b6a),
    353                                                  DECORR(0xf298803d),
    354                                                  DECORR(0xef98be92),
    355                                                  DECORR(0x09ea1706),
    356                                                  DECORR(0x28fbdff4),
    357                                                  DECORR(0x1a869eb9),
    358                                                  DECORR(0xdeefe147),
    359                                                  DECORR(0xcde2adda),
    360                                                  DECORR(0x13ddc619),
    361                                                  DECORR(0x40000000),
    362                                              },
    363                                              {
    364                                                  DECORR(0x041d7dbf),
    365                                                  DECORR(0x01b7309c),
    366                                                  DECORR(0xfb599834),
    367                                                  DECORR(0x092fc5ed),
    368                                                  DECORR(0xf2fd7c25),
    369                                                  DECORR(0xdd51e2eb),
    370                                                  DECORR(0xf62fe72b),
    371                                                  DECORR(0x0b15d588),
    372                                                  DECORR(0xf1f091a7),
    373                                                  DECORR(0xed1bbbfe),
    374                                                  DECORR(0x03526899),
    375                                                  DECORR(0x180cb256),
    376                                                  DECORR(0xecf1433d),
    377                                                  DECORR(0xf626ab95),
    378                                                  DECORR(0x197dd27e),
    379                                                  DECORR(0x40000000),
    380                                              },
    381                                              {
    382                                                  DECORR(0x157a786c),
    383                                                  DECORR(0x0028c98c),
    384                                                  DECORR(0xf5eff57b),
    385                                                  DECORR(0x11f7d04f),
    386                                                  DECORR(0xf390d28d),
    387                                                  DECORR(0x18947081),
    388                                                  DECORR(0xe5dc2319),
    389                                                  DECORR(0xf4cc0235),
    390                                                  DECORR(0x2394d47f),
    391                                                  DECORR(0xe069230e),
    392                                                  DECORR(0x03a1a773),
    393                                                  DECORR(0xfbc9b092),
    394                                                  DECORR(0x15a0173b),
    395                                                  DECORR(0x0e9ecdf0),
    396                                                  DECORR(0xd309b2c7),
    397                                                  DECORR(0x40000000),
    398                                              },
    399                                              {
    400                                                  DECORR(0xe0ce703b),
    401                                                  DECORR(0xe508b672),
    402                                                  DECORR(0xef362398),
    403                                                  DECORR(0xffe788ef),
    404                                                  DECORR(0x2fda3749),
    405                                                  DECORR(0x4671c0c6),
    406                                                  DECORR(0x3c003494),
    407                                                  DECORR(0x2387707c),
    408                                                  DECORR(0xd2107d2e),
    409                                                  DECORR(0xb3e47e08),
    410                                                  DECORR(0xacd0abca),
    411                                                  DECORR(0xc70791df),
    412                                                  DECORR(0x0b586e85),
    413                                                  DECORR(0x2f11cda7),
    414                                                  DECORR(0x3a4a210b),
    415                                                  DECORR(0x40000000),
    416                                              },
    417 };
    418 
    419 RAM_ALIGN
    420 const FIXP_DECORR DecorrNumeratorReal2_LD[MAX_DECORR_SEED_LD]
    421                                          [DECORR_FILTER_ORDER_BAND_2_LD + 1 +
    422                                           DECORR_ZERO_PADDING] = {
    423                                              {
    424                                                  DECORR(0xffb4a234),
    425                                                  DECORR(0x01ac71a2),
    426                                                  DECORR(0xf2bca010),
    427                                                  DECORR(0xfe3d7593),
    428                                                  DECORR(0x093e9976),
    429                                                  DECORR(0xf2c5f3f5),
    430                                                  DECORR(0x40000000),
    431                                              },
    432                                              {
    433                                                  DECORR(0xe303afb8),
    434                                                  DECORR(0xcd70c2bb),
    435                                                  DECORR(0xf1e2ad7e),
    436                                                  DECORR(0x0c8ffbe2),
    437                                                  DECORR(0x21f80abf),
    438                                                  DECORR(0x3d08410c),
    439                                                  DECORR(0x40000000),
    440                                              },
    441                                              {
    442                                                  DECORR(0xe26809d5),
    443                                                  DECORR(0x0efbcfa4),
    444                                                  DECORR(0x210c1a97),
    445                                                  DECORR(0xfe60af4e),
    446                                                  DECORR(0xeda01a51),
    447                                                  DECORR(0x00faf468),
    448                                                  DECORR(0x40000000),
    449                                              },
    450                                              {
    451                                                  DECORR(0x1edc5d64),
    452                                                  DECORR(0xe5b2e35c),
    453                                                  DECORR(0xe94b1c45),
    454                                                  DECORR(0x30a6f1e1),
    455                                                  DECORR(0xf04e52de),
    456                                                  DECORR(0xe30de45a),
    457                                                  DECORR(0x40000000),
    458                                              },
    459 };
    460 
    461 RAM_ALIGN
    462 const FIXP_DECORR DecorrNumeratorReal3_LD[MAX_DECORR_SEED_LD]
    463                                          [DECORR_FILTER_ORDER_BAND_3_LD + 1] = {
    464                                              {
    465                                                  DECORR(0x0248e8a7),
    466                                                  DECORR(0xfde9583b),
    467                                                  DECORR(0x084823bb),
    468                                                  DECORR(0x40000000),
    469                                              },
    470                                              {
    471                                                  DECORR(0x1db22d0e),
    472                                                  DECORR(0xfc773992),
    473                                                  DECORR(0x0e819a74),
    474                                                  DECORR(0x40000000),
    475                                              },
    476                                              {
    477                                                  DECORR(0x0fcb923a),
    478                                                  DECORR(0x0154b7ff),
    479                                                  DECORR(0xe70cb647),
    480                                                  DECORR(0x40000000),
    481                                              },
    482                                              {
    483                                                  DECORR(0xe39f559b),
    484                                                  DECORR(0xe06dd6ca),
    485                                                  DECORR(0x19f71f71),
    486                                                  DECORR(0x40000000),
    487                                              },
    488 };
    489 
    490 FIXP_DBL *getAddrDirectSignalMaxVal(HANDLE_DECORR_DEC self) {
    491   return &(self->ducker.maxValDirectData);
    492 }
    493 
    494 static INT DecorrFilterInit(DECORR_FILTER_INSTANCE *const self,
    495                             FIXP_MPS *pStateBufferCplx,
    496                             FIXP_DBL *pDelayBufferCplx, INT *offsetStateBuffer,
    497                             INT *offsetDelayBuffer, INT const decorr_seed,
    498                             INT const reverb_band, INT const useFractDelay,
    499                             INT const noSampleDelay, INT const filterOrder,
    500                             FDK_DECORR_TYPE const decorrType) {
    501   INT errorCode = 0;
    502   switch (decorrType) {
    503     case DECORR_USAC:
    504       if (useFractDelay) {
    505         return 1;
    506       } else {
    507         FDK_ASSERT(decorr_seed == 0);
    508 
    509         switch (reverb_band) {
    510           case 0:
    511             self->numeratorReal = DecorrNumeratorReal0_USAC[decorr_seed];
    512             break;
    513           case 1:
    514             self->numeratorReal = DecorrNumeratorReal1_USAC[decorr_seed];
    515             break;
    516           case 2:
    517             self->numeratorReal = DecorrNumeratorReal2_USAC[decorr_seed];
    518             break;
    519           case 3:
    520             self->numeratorReal = DecorrNumeratorReal3_USAC[decorr_seed];
    521             break;
    522         }
    523       }
    524       break;
    525     case DECORR_LD:
    526       FDK_ASSERT(decorr_seed < MAX_DECORR_SEED_LD);
    527       switch (reverb_band) {
    528         case 0:
    529           self->numeratorReal = NULL;
    530           break;
    531         case 1:
    532           self->numeratorReal = DecorrNumeratorReal1_LD[decorr_seed];
    533           break;
    534         case 2:
    535           self->numeratorReal = DecorrNumeratorReal2_LD[decorr_seed];
    536           break;
    537         case 3:
    538           self->numeratorReal = DecorrNumeratorReal3_LD[decorr_seed];
    539           break;
    540       }
    541       break;
    542     default:
    543       return 1;
    544   }
    545 
    546   self->stateCplx = pStateBufferCplx + (*offsetStateBuffer);
    547   *offsetStateBuffer += 2 * filterOrder;
    548   self->DelayBufferCplx = pDelayBufferCplx + (*offsetDelayBuffer);
    549   *offsetDelayBuffer += 2 * noSampleDelay;
    550 
    551   return errorCode;
    552 }
    553 
    554 /*******************************************************************************
    555 *******************************************************************************/
    556 static INT DecorrFilterInitPS(DECORR_FILTER_INSTANCE *const self,
    557                               FIXP_MPS *pStateBufferCplx,
    558                               FIXP_DBL *pDelayBufferCplx,
    559                               INT *offsetStateBuffer, INT *offsetDelayBuffer,
    560                               INT const hybridBand, INT const reverbBand,
    561                               INT const noSampleDelay) {
    562   INT errorCode = 0;
    563 
    564   if (reverbBand == 0) {
    565     self->coeffsPacked = DecorrPsCoeffsCplx[hybridBand];
    566 
    567     self->stateCplx = pStateBufferCplx + (*offsetStateBuffer);
    568     *offsetStateBuffer += 2 * DECORR_FILTER_ORDER_PS;
    569   }
    570 
    571   self->DelayBufferCplx = pDelayBufferCplx + (*offsetDelayBuffer);
    572   *offsetDelayBuffer += 2 * noSampleDelay;
    573 
    574   return errorCode;
    575 }
    576 
    577 LNK_SECTION_CODE_L1
    578 static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
    579                                  FIXP_DBL *dataRealIn, FIXP_DBL *dataImagIn,
    580                                  FIXP_DBL *dataRealOut, FIXP_DBL *dataImagOut,
    581                                  INT start, INT stop,
    582                                  INT reverbBandNoSampleDelay,
    583                                  INT reverbBandDelayBufferIndex) {
    584   INT i;
    585   INT offset = 2 * reverbBandNoSampleDelay;
    586   FIXP_MPS *pDelayBuffer =
    587       &filter[start].DelayBufferCplx[reverbBandDelayBufferIndex];
    588 
    589   /* Memory for the delayline has been allocated in a consecutive order, so we
    590      can address from filter to filter with a constant length.
    591      Be aware that real and imaginary part of the delayline are stored in
    592      interleaved order.
    593   */
    594   if (dataImagIn == NULL) {
    595     for (i = start; i < stop; i++) {
    596       FIXP_DBL tmp;
    597 
    598       tmp = *pDelayBuffer;
    599       *pDelayBuffer = dataRealIn[i];
    600       dataRealOut[i] = tmp;
    601       pDelayBuffer += offset;
    602     }
    603   } else {
    604     if ((i = stop - start) != 0) {
    605       dataRealIn += start;
    606       dataImagIn += start;
    607       dataRealOut += start;
    608       dataImagOut += start;
    609 #ifdef FUNCTION_DecorrFilterApplyPASS_func1
    610       DecorrFilterApplyPASS_func1(i, dataRealIn, dataImagIn, dataRealOut,
    611                                   dataImagOut, pDelayBuffer, offset);
    612 #else
    613       do {
    614         FIXP_DBL delay_re, delay_im, real, imag;
    615 
    616         real = *dataRealIn++;
    617         imag = *dataImagIn++;
    618         delay_re = pDelayBuffer[0];
    619         delay_im = pDelayBuffer[1];
    620         pDelayBuffer[0] = real;
    621         pDelayBuffer[1] = imag;
    622         *dataRealOut++ = delay_re;
    623         *dataImagOut++ = delay_im;
    624         pDelayBuffer += offset;
    625       } while (--i != 0);
    626 #endif
    627     }
    628   }
    629 
    630   return (INT)0;
    631 }
    632 
    633 #ifndef FUNCTION_DecorrFilterApplyREAL
    634 LNK_SECTION_CODE_L1
    635 static INT DecorrFilterApplyREAL(DECORR_FILTER_INSTANCE const filter[],
    636                                  FIXP_DBL *dataRealIn, FIXP_DBL *dataImagIn,
    637                                  FIXP_DBL *dataRealOut, FIXP_DBL *dataImagOut,
    638                                  INT start, INT stop, INT reverbFilterOrder,
    639                                  INT reverbBandNoSampleDelay,
    640                                  INT reverbBandDelayBufferIndex) {
    641   INT i, j;
    642   FIXP_DBL xReal, xImag, yReal, yImag;
    643 
    644   const FIXP_DECORR *pFilter = filter[start].numeratorReal;
    645 
    646   INT offsetDelayBuffer = (2 * reverbBandNoSampleDelay) - 1;
    647   FIXP_MPS *pDelayBuffer =
    648       &filter[start].DelayBufferCplx[reverbBandDelayBufferIndex];
    649 
    650   INT offsetStates = 2 * reverbFilterOrder;
    651   FIXP_DBL *pStates = filter[start].stateCplx;
    652 
    653   /* Memory for the delayline has been allocated in a consecutive order, so we
    654      can address from filter to filter with a constant length. The same is valid
    655      for the states.
    656      Be aware that real and imaginary part of the delayline and the states are
    657      stored in interleaved order.
    658      All filter in a reverb band have the same filter coefficients.
    659      Exploit symmetry: numeratorReal[i] =
    660      denominatorReal[reverbFilterLength-1-i] Do not accumulate the highest
    661      states which are always zero.
    662   */
    663   if (reverbFilterOrder == 2) {
    664     FIXP_DECORR nFilt0L, nFilt0H;
    665 
    666     nFilt0L = pFilter[0];
    667     nFilt0H = pFilter[1];
    668 
    669     for (i = start; i < stop; i++) {
    670       xReal = *pDelayBuffer;
    671       *pDelayBuffer = dataRealIn[i];
    672       pDelayBuffer++;
    673 
    674       xImag = *pDelayBuffer;
    675       *pDelayBuffer = dataImagIn[i];
    676       pDelayBuffer += offsetDelayBuffer;
    677 
    678       yReal = (pStates[0] + fMultDiv2(xReal, nFilt0L)) << FILTER_SF;
    679       yImag = (pStates[1] + fMultDiv2(xImag, nFilt0L)) << FILTER_SF;
    680 
    681       dataRealOut[i] = yReal;
    682       dataImagOut[i] = yImag;
    683 
    684       pStates[0] =
    685           pStates[2] + fMultDiv2(xReal, nFilt0H) - fMultDiv2(yReal, nFilt0H);
    686       pStates[1] =
    687           pStates[3] + fMultDiv2(xImag, nFilt0H) - fMultDiv2(yImag, nFilt0H);
    688       pStates[2] = (xReal >> FILTER_SF) - fMultDiv2(yReal, nFilt0L);
    689       pStates[3] = (xImag >> FILTER_SF) - fMultDiv2(yImag, nFilt0L);
    690       pStates += offsetStates;
    691     }
    692   } else if (reverbFilterOrder == 3) {
    693     FIXP_DECORR nFilt0L, nFilt0H, nFilt1L;
    694 
    695     nFilt0L = pFilter[0];
    696     nFilt0H = pFilter[1];
    697     nFilt1L = pFilter[2];
    698 
    699     for (i = start; i < stop; i++) {
    700       xReal = *pDelayBuffer;
    701       *pDelayBuffer = dataRealIn[i];
    702       pDelayBuffer++;
    703 
    704       xImag = *pDelayBuffer;
    705       *pDelayBuffer = dataImagIn[i];
    706       pDelayBuffer += offsetDelayBuffer;
    707 
    708       yReal = (pStates[0] + fMultDiv2(xReal, nFilt0L)) << FILTER_SF;
    709       yImag = (pStates[1] + fMultDiv2(xImag, nFilt0L)) << FILTER_SF;
    710 
    711       dataRealOut[i] = yReal;
    712       dataImagOut[i] = yImag;
    713 
    714       pStates[0] =
    715           pStates[2] + fMultDiv2(xReal, nFilt0H) - fMultDiv2(yReal, nFilt1L);
    716       pStates[1] =
    717           pStates[3] + fMultDiv2(xImag, nFilt0H) - fMultDiv2(yImag, nFilt1L);
    718       pStates[2] =
    719           pStates[4] + fMultDiv2(xReal, nFilt1L) - fMultDiv2(yReal, nFilt0H);
    720       pStates[3] =
    721           pStates[5] + fMultDiv2(xImag, nFilt1L) - fMultDiv2(yImag, nFilt0H);
    722       pStates[4] = (xReal >> FILTER_SF) - fMultDiv2(yReal, nFilt0L);
    723       pStates[5] = (xImag >> FILTER_SF) - fMultDiv2(yImag, nFilt0L);
    724       pStates += offsetStates;
    725     }
    726   } else if (reverbFilterOrder == 6) {
    727     FIXP_DECORR nFilt0L, nFilt0H, nFilt1L, nFilt1H, nFilt2L, nFilt2H;
    728 
    729     nFilt0L = pFilter[0];
    730     nFilt0H = pFilter[1];
    731     nFilt1L = pFilter[2];
    732     nFilt1H = pFilter[3];
    733     nFilt2L = pFilter[4];
    734     nFilt2H = pFilter[5];
    735 
    736     for (i = start; i < stop; i++) {
    737       xReal = *pDelayBuffer;
    738       *pDelayBuffer = dataRealIn[i];
    739       pDelayBuffer++;
    740 
    741       xImag = *pDelayBuffer;
    742       *pDelayBuffer = dataImagIn[i];
    743       pDelayBuffer += offsetDelayBuffer;
    744 
    745       yReal = (pStates[0] + fMultDiv2(xReal, nFilt0L)) << FILTER_SF;
    746       yImag = (pStates[1] + fMultDiv2(xImag, nFilt0L)) << FILTER_SF;
    747       dataRealOut[i] = yReal;
    748       dataImagOut[i] = yImag;
    749 
    750       pStates[0] =
    751           pStates[2] + fMultDiv2(xReal, nFilt0H) - fMultDiv2(yReal, nFilt2H);
    752       pStates[1] =
    753           pStates[3] + fMultDiv2(xImag, nFilt0H) - fMultDiv2(yImag, nFilt2H);
    754       pStates[2] =
    755           pStates[4] + fMultDiv2(xReal, nFilt1L) - fMultDiv2(yReal, nFilt2L);
    756       pStates[3] =
    757           pStates[5] + fMultDiv2(xImag, nFilt1L) - fMultDiv2(yImag, nFilt2L);
    758       pStates[4] =
    759           pStates[6] + fMultDiv2(xReal, nFilt1H) - fMultDiv2(yReal, nFilt1H);
    760       pStates[5] =
    761           pStates[7] + fMultDiv2(xImag, nFilt1H) - fMultDiv2(yImag, nFilt1H);
    762       pStates[6] =
    763           pStates[8] + fMultDiv2(xReal, nFilt2L) - fMultDiv2(yReal, nFilt1L);
    764       pStates[7] =
    765           pStates[9] + fMultDiv2(xImag, nFilt2L) - fMultDiv2(yImag, nFilt1L);
    766       pStates[8] =
    767           pStates[10] + fMultDiv2(xReal, nFilt2H) - fMultDiv2(yReal, nFilt0H);
    768       pStates[9] =
    769           pStates[11] + fMultDiv2(xImag, nFilt2H) - fMultDiv2(yImag, nFilt0H);
    770       pStates[10] = (xReal >> FILTER_SF) - fMultDiv2(yReal, nFilt0L);
    771       pStates[11] = (xImag >> FILTER_SF) - fMultDiv2(yImag, nFilt0L);
    772       pStates += offsetStates;
    773     }
    774   } else {
    775     FIXP_DECORR nFilt0L, nFilt0H;
    776     for (i = start; i < stop; i++) {
    777       xReal = *pDelayBuffer;
    778       *pDelayBuffer = dataRealIn[i];
    779       pDelayBuffer++;
    780 
    781       xImag = *pDelayBuffer;
    782       *pDelayBuffer = dataImagIn[i];
    783       pDelayBuffer += offsetDelayBuffer;
    784 
    785       nFilt0L = pFilter[0];
    786       yReal = (pStates[0] + fMultDiv2(xReal, nFilt0L)) << 2;
    787       yImag = (pStates[1] + fMultDiv2(xImag, nFilt0L)) << 2;
    788       dataRealOut[i] = yReal;
    789       dataImagOut[i] = yImag;
    790 
    791       for (j = 1; j < reverbFilterOrder; j++) {
    792         nFilt0L = pFilter[j];
    793         nFilt0H = pFilter[reverbFilterOrder - j];
    794         pStates[2 * j - 2] = pStates[2 * j] + fMultDiv2(xReal, nFilt0L) -
    795                              fMultDiv2(yReal, nFilt0H);
    796         pStates[2 * j - 1] = pStates[2 * j + 1] + fMultDiv2(xImag, nFilt0L) -
    797                              fMultDiv2(yImag, nFilt0H);
    798       }
    799       nFilt0L = pFilter[j];
    800       nFilt0H = pFilter[reverbFilterOrder - j];
    801       pStates[2 * j - 2] =
    802           fMultDiv2(xReal, nFilt0L) - fMultDiv2(yReal, nFilt0H);
    803       pStates[2 * j - 1] =
    804           fMultDiv2(xImag, nFilt0L) - fMultDiv2(yImag, nFilt0H);
    805 
    806       pStates += offsetStates;
    807     }
    808   }
    809 
    810   return (INT)0;
    811 }
    812 #endif /* #ifndef FUNCTION_DecorrFilterApplyREAL */
    813 
    814 #ifndef FUNCTION_DecorrFilterApplyCPLX_PS
    815 LNK_SECTION_CODE_L1
    816 static INT DecorrFilterApplyCPLX_PS(
    817     DECORR_FILTER_INSTANCE const filter[], FIXP_DBL *dataRealIn,
    818     FIXP_DBL *dataImagIn, FIXP_DBL *dataRealOut, FIXP_DBL *dataImagOut,
    819     INT start, INT stop, INT reverbFilterOrder, INT reverbBandNoSampleDelay,
    820     INT reverbBandDelayBufferIndex, UCHAR *stateBufferOffset) {
    821   /* r = real, j = imaginary */
    822   FIXP_DBL r_data_a, j_data_a, r_data_b, j_data_b, r_stage_mult, j_stage_mult;
    823   FIXP_STP rj_coeff;
    824 
    825   /* get pointer to current position in input delay buffer of filter with
    826    * starting-index */
    827   FIXP_DBL *pDelayBuffer =
    828       &filter[start].DelayBufferCplx[reverbBandDelayBufferIndex]; /* increases
    829                                                                      by 2 every
    830                                                                      other call
    831                                                                      of this
    832                                                                      function */
    833   /* determine the increment for this pointer to get to the correct position in
    834    * the delay buffer of the next filter */
    835   INT offsetDelayBuffer = (2 * reverbBandNoSampleDelay) - 1;
    836 
    837   /* pointer to current position in state buffer */
    838   FIXP_DBL *pStates = filter[start].stateCplx;
    839   INT pStatesIncrement = 2 * reverbFilterOrder;
    840 
    841   /* stateBufferOffset-pointers */
    842   FIXP_DBL *pStateBufferOffset0 = pStates + stateBufferOffset[0];
    843   FIXP_DBL *pStateBufferOffset1 = pStates + stateBufferOffset[1];
    844   FIXP_DBL *pStateBufferOffset2 = pStates + stateBufferOffset[2];
    845 
    846   /* traverse all hybrid-bands inbetween start- and stop-index */
    847   for (int i = start; i < stop; i++) {
    848     /* 1. input delay (real/imaginary values interleaved) */
    849 
    850     /* load delayed real input value */
    851     r_data_a = *pDelayBuffer;
    852     /* store incoming real data value to delay buffer and increment pointer */
    853     *pDelayBuffer++ = dataRealIn[i];
    854 
    855     /* load delayed imaginary input value */
    856     j_data_a = *pDelayBuffer;
    857     /* store incoming imaginary data value to delay buffer */
    858     *pDelayBuffer = dataImagIn[i];
    859     /* increase delay buffer by offset */
    860     pDelayBuffer += offsetDelayBuffer;
    861 
    862     /* 2. Phi(k)-stage */
    863 
    864     /* create pointer to coefficient table (real and imaginary coefficients
    865      * interleaved) */
    866     const FIXP_STP *pCoeffs = filter[i].coeffsPacked;
    867 
    868     /* the first two entries of the coefficient table are the
    869      * Phi(k)-multiplicants */
    870     rj_coeff = *pCoeffs++;
    871     /* multiply value from input delay buffer by looked-up values */
    872     cplxMultDiv2(&r_data_b, &j_data_b, r_data_a, j_data_a, rj_coeff);
    873 
    874     /* 3. process all three filter stages */
    875 
    876     /* stage 0 */
    877 
    878     /* get coefficients from lookup table */
    879     rj_coeff = *pCoeffs++;
    880 
    881     /* multiply output of last stage by coefficient */
    882     cplxMultDiv2(&r_stage_mult, &j_stage_mult, r_data_b, j_data_b, rj_coeff);
    883     r_stage_mult <<= 1;
    884     j_stage_mult <<= 1;
    885 
    886     /* read and add value from state buffer (this is the input for the next
    887      * stage) */
    888     r_data_a = r_stage_mult + pStateBufferOffset0[0];
    889     j_data_a = j_stage_mult + pStateBufferOffset0[1];
    890 
    891     /* negate r_data_a to perform multiplication with complex conjugate of
    892      * rj_coeff */
    893     cplxMultDiv2(&r_stage_mult, &j_stage_mult, -r_data_a, j_data_a, rj_coeff);
    894 
    895     /* add stage input to shifted result */
    896     r_stage_mult = r_data_b + (r_stage_mult << 1);
    897     j_stage_mult = j_data_b - (j_stage_mult << 1);
    898 
    899     /* store result to state buffer */
    900     pStateBufferOffset0[0] = r_stage_mult;
    901     pStateBufferOffset0[1] = j_stage_mult;
    902     pStateBufferOffset0 += pStatesIncrement;
    903 
    904     /* stage 1 */
    905 
    906     /* get coefficients from lookup table */
    907     rj_coeff = *pCoeffs++;
    908 
    909     /* multiply output of last stage by coefficient */
    910     cplxMultDiv2(&r_stage_mult, &j_stage_mult, r_data_a, j_data_a, rj_coeff);
    911     r_stage_mult <<= 1;
    912     j_stage_mult <<= 1;
    913 
    914     /* read and add value from state buffer (this is the input for the next
    915      * stage) */
    916     r_data_b = r_stage_mult + pStateBufferOffset1[0];
    917     j_data_b = j_stage_mult + pStateBufferOffset1[1];
    918 
    919     /* negate r_data_b to perform multiplication with complex conjugate of
    920      * rj_coeff */
    921     cplxMultDiv2(&r_stage_mult, &j_stage_mult, -r_data_b, j_data_b, rj_coeff);
    922 
    923     /* add stage input to shifted result */
    924     r_stage_mult = r_data_a + (r_stage_mult << 1);
    925     j_stage_mult = j_data_a - (j_stage_mult << 1);
    926 
    927     /* store result to state buffer */
    928     pStateBufferOffset1[0] = r_stage_mult;
    929     pStateBufferOffset1[1] = j_stage_mult;
    930     pStateBufferOffset1 += pStatesIncrement;
    931 
    932     /* stage 2 */
    933 
    934     /* get coefficients from lookup table */
    935     rj_coeff = *pCoeffs++;
    936 
    937     /* multiply output of last stage by coefficient */
    938     cplxMultDiv2(&r_stage_mult, &j_stage_mult, r_data_b, j_data_b, rj_coeff);
    939     r_stage_mult <<= 1;
    940     j_stage_mult <<= 1;
    941 
    942     /* read and add value from state buffer (this is the input for the next
    943      * stage) */
    944     r_data_a = r_stage_mult + pStateBufferOffset2[0];
    945     j_data_a = j_stage_mult + pStateBufferOffset2[1];
    946 
    947     /* negate r_data_a to perform multiplication with complex conjugate of
    948      * rj_coeff */
    949     cplxMultDiv2(&r_stage_mult, &j_stage_mult, -r_data_a, j_data_a, rj_coeff);
    950 
    951     /* add stage input to shifted result */
    952     r_stage_mult = r_data_b + (r_stage_mult << 1);
    953     j_stage_mult = j_data_b - (j_stage_mult << 1);
    954 
    955     /* store result to state buffer */
    956     pStateBufferOffset2[0] = r_stage_mult;
    957     pStateBufferOffset2[1] = j_stage_mult;
    958     pStateBufferOffset2 += pStatesIncrement;
    959 
    960     /* write filter output */
    961     dataRealOut[i] = r_data_a << 1;
    962     dataImagOut[i] = j_data_a << 1;
    963 
    964   } /* end of band/filter loop (outer loop) */
    965 
    966   /* update stateBufferOffset with respect to ring buffer boundaries */
    967   if (stateBufferOffset[0] == 4)
    968     stateBufferOffset[0] = 0;
    969   else
    970     stateBufferOffset[0] += 2;
    971 
    972   if (stateBufferOffset[1] == 12)
    973     stateBufferOffset[1] = 6;
    974   else
    975     stateBufferOffset[1] += 2;
    976 
    977   if (stateBufferOffset[2] == 22)
    978     stateBufferOffset[2] = 14;
    979   else
    980     stateBufferOffset[2] += 2;
    981 
    982   return (INT)0;
    983 }
    984 
    985 #endif /* FUNCTION_DecorrFilterApplyCPLX_PS */
    986 
    987 /*******************************************************************************
    988 *******************************************************************************/
    989 static INT DuckerInit(DUCKER_INSTANCE *const self, int const hybridBands,
    990                       int partiallyComplex, const FDK_DUCKER_TYPE duckerType,
    991                       const int nParamBands, int initStatesFlag) {
    992   INT errorCode = 0;
    993 
    994   if (self) {
    995     switch (nParamBands) {
    996       case (20):
    997         FDK_ASSERT(hybridBands == 71);
    998         self->mapHybBands2ProcBands = kernels_20_to_71_PS;
    999         self->mapProcBands2HybBands = kernels_20_to_71_offset_PS;
   1000         self->parameterBands = (20);
   1001         break;
   1002       case (28):
   1003 
   1004         self->mapHybBands2ProcBands = kernels_28_to_71;
   1005         self->mapProcBands2HybBands = kernels_28_to_71_offset;
   1006         self->parameterBands = (28);
   1007         break;
   1008       case (23):
   1009         FDK_ASSERT(hybridBands == 64 || hybridBands == 32);
   1010         self->mapHybBands2ProcBands = kernels_23_to_64;
   1011         self->mapProcBands2HybBands = kernels_23_to_64_offset;
   1012         self->parameterBands = (23);
   1013         break;
   1014       default:
   1015         return 1;
   1016     }
   1017     self->qs_next = &self->mapProcBands2HybBands[1];
   1018 
   1019     self->maxValDirectData = FL2FXCONST_DBL(-1.0f);
   1020     self->maxValReverbData = FL2FXCONST_DBL(-1.0f);
   1021     self->scaleDirectNrg = 2 * DUCKER_MAX_NRG_SCALE;
   1022     self->scaleReverbNrg = 2 * DUCKER_MAX_NRG_SCALE;
   1023     self->scaleSmoothDirRevNrg = 2 * DUCKER_MAX_NRG_SCALE;
   1024     self->headroomSmoothDirRevNrg = 2 * DUCKER_MAX_NRG_SCALE;
   1025     self->hybridBands = hybridBands;
   1026     self->partiallyComplex = partiallyComplex;
   1027 
   1028     if (initStatesFlag && (duckerType == DUCKER_PS)) {
   1029       int pb;
   1030       for (pb = 0; pb < self->parameterBands; pb++) {
   1031         self->SmoothDirRevNrg[pb] = (FIXP_MPS)0;
   1032       }
   1033     }
   1034   } else
   1035     errorCode = 1;
   1036 
   1037   return errorCode;
   1038 }
   1039 
   1040   /*******************************************************************************
   1041   *******************************************************************************/
   1042 
   1043 #ifndef FUNCTION_DuckerCalcEnergy
   1044 static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
   1045                             FIXP_DBL const inputReal[(71)],
   1046                             FIXP_DBL const inputImag[(71)],
   1047                             FIXP_DBL energy[(28)], FIXP_DBL inputMaxVal,
   1048                             SCHAR *nrgScale, int mode, /* 1:(ps) 0:(else) */
   1049                             int startHybBand) {
   1050   INT err = 0;
   1051   int qs, maxHybBand;
   1052   int maxHybridBand = self->hybridBands - 1;
   1053 
   1054   maxHybBand = maxHybridBand;
   1055 
   1056   FDKmemclear(energy, (28) * sizeof(FIXP_DBL));
   1057 
   1058   if (mode == 1) {
   1059     int pb;
   1060     int clz;
   1061     FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
   1062 
   1063     if (maxVal == FL2FXCONST_DBL(-1.0f)) {
   1064 #ifdef FUNCTION_DuckerCalcEnergy_func2
   1065       maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
   1066                                       maxHybBand, maxHybridBand);
   1067 #else
   1068       FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
   1069       for (qs = startHybBand; qs <= maxHybBand; qs++) {
   1070         localMaxVal |= fAbs(inputReal[qs]);
   1071         localMaxVal |= fAbs(inputImag[qs]);
   1072       }
   1073       for (; qs <= maxHybridBand; qs++) {
   1074         localMaxVal |= fAbs(inputReal[qs]);
   1075       }
   1076       maxVal = localMaxVal;
   1077 #endif
   1078     }
   1079 
   1080     clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
   1081     clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
   1082     *nrgScale = (SCHAR)clz << 1;
   1083 
   1084     /* Initialize pb since it would stay uninitialized for the case startHybBand
   1085      * > maxHybBand. */
   1086     pb = SpatialDecGetProcessingBand(maxHybBand, self->mapHybBands2ProcBands);
   1087     for (qs = startHybBand; qs <= maxHybBand; qs++) {
   1088       pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
   1089       energy[pb] +=
   1090           (fPow2Div2(inputReal[qs] << clz) + fPow2Div2(inputImag[qs] << clz));
   1091     }
   1092     pb++;
   1093 
   1094     for (; pb <= SpatialDecGetProcessingBand(maxHybridBand,
   1095                                              self->mapHybBands2ProcBands);
   1096          pb++) {
   1097       FDK_ASSERT(pb != SpatialDecGetProcessingBand(
   1098                            qs - 1, self->mapHybBands2ProcBands));
   1099       int qs_next;
   1100       FIXP_DBL nrg = 0;
   1101       qs_next = (int)self->qs_next[pb];
   1102       for (; qs < qs_next; qs++) {
   1103         nrg += fPow2Div2(inputReal[qs] << clz);
   1104       }
   1105       energy[pb] = nrg;
   1106     }
   1107   } else {
   1108     int clz;
   1109     FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
   1110 
   1111     maxVal = inputMaxVal;
   1112 
   1113     if (maxVal == FL2FXCONST_DBL(-1.0f)) {
   1114 #ifdef FUNCTION_DuckerCalcEnergy_func2
   1115       maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
   1116                                       maxHybBand, maxHybridBand);
   1117 #else
   1118       FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
   1119       for (qs = startHybBand; qs <= maxHybBand; qs++) {
   1120         localMaxVal |= fAbs(inputReal[qs]);
   1121         localMaxVal |= fAbs(inputImag[qs]);
   1122       }
   1123       for (; qs <= maxHybridBand; qs++) {
   1124         localMaxVal |= fAbs(inputReal[qs]);
   1125       }
   1126       maxVal = localMaxVal;
   1127 #endif
   1128     }
   1129 
   1130     clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
   1131     clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
   1132     *nrgScale = (SCHAR)clz << 1;
   1133 
   1134 #ifdef FUNCTION_DuckerCalcEnergy_func4
   1135     DuckerCalcEnergy_func4(inputReal, inputImag, energy,
   1136                            self->mapHybBands2ProcBands, clz, startHybBand,
   1137                            maxHybBand, maxHybridBand);
   1138 #else
   1139     for (qs = startHybBand; qs <= maxHybBand; qs++) {
   1140       int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
   1141       energy[pb] +=
   1142           (fPow2Div2(inputReal[qs] << clz) + fPow2Div2(inputImag[qs] << clz));
   1143     }
   1144 
   1145     for (; qs <= maxHybridBand; qs++) {
   1146       int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
   1147       energy[pb] += fPow2Div2(inputReal[qs] << clz);
   1148     }
   1149 #endif /* FUNCTION_DuckerCalcEnergy_func4 */
   1150   }
   1151 
   1152   {
   1153     /* Catch overflows which have been observed in erred bitstreams to avoid
   1154      * assertion failures later. */
   1155     int pb;
   1156     for (pb = 0; pb < (28); pb++) {
   1157       energy[pb] = (FIXP_DBL)((LONG)energy[pb] & (LONG)MAXVAL_DBL);
   1158     }
   1159   }
   1160   return err;
   1161 }
   1162 #endif /* #ifndef FUNCTION_DuckerCalcEnergy */
   1163 
   1164 LNK_SECTION_CODE_L1
   1165 static INT DuckerApply(DUCKER_INSTANCE *const self,
   1166                        FIXP_DBL const directNrg[(28)],
   1167                        FIXP_DBL outputReal[(71)], FIXP_DBL outputImag[(71)],
   1168                        int startHybBand) {
   1169   INT err = 0;
   1170   int qs = startHybBand;
   1171   int qs_next = 0;
   1172   int pb = 0;
   1173   int startParamBand = 0;
   1174   int hybBands;
   1175   int hybridBands = self->hybridBands;
   1176 
   1177   C_ALLOC_SCRATCH_START(reverbNrg, FIXP_DBL, (28));
   1178 
   1179   FIXP_DBL *smoothDirRevNrg = &self->SmoothDirRevNrg[0];
   1180   FIXP_DUCK_GAIN duckGain = 0;
   1181 
   1182   int doScaleNrg = 0;
   1183   int scaleDirectNrg = 0;
   1184   int scaleReverbNrg = 0;
   1185   int scaleSmoothDirRevNrg = 0;
   1186   FIXP_DBL maxDirRevNrg = FL2FXCONST_DBL(0.0);
   1187 
   1188   hybBands = hybridBands;
   1189 
   1190   startParamBand =
   1191       SpatialDecGetProcessingBand(startHybBand, self->mapHybBands2ProcBands);
   1192 
   1193   DuckerCalcEnergy(self, outputReal, outputImag, reverbNrg,
   1194                    self->maxValReverbData, &(self->scaleReverbNrg), 0,
   1195                    startHybBand);
   1196 
   1197   if ((self->scaleDirectNrg != self->scaleReverbNrg) ||
   1198       (self->scaleDirectNrg != self->scaleSmoothDirRevNrg) ||
   1199       (self->headroomSmoothDirRevNrg == 0)) {
   1200     int scale;
   1201 
   1202     scale = fixMin(self->scaleDirectNrg, self->scaleSmoothDirRevNrg +
   1203                                              self->headroomSmoothDirRevNrg - 1);
   1204     scale = fixMin(scale, self->scaleReverbNrg);
   1205 
   1206     scaleDirectNrg = fMax(fMin(self->scaleDirectNrg - scale, (DFRACT_BITS - 1)),
   1207                           -(DFRACT_BITS - 1));
   1208     scaleReverbNrg = fMax(fMin(self->scaleReverbNrg - scale, (DFRACT_BITS - 1)),
   1209                           -(DFRACT_BITS - 1));
   1210     scaleSmoothDirRevNrg =
   1211         fMax(fMin(self->scaleSmoothDirRevNrg - scale, (DFRACT_BITS - 1)),
   1212              -(DFRACT_BITS - 1));
   1213 
   1214     self->scaleSmoothDirRevNrg = (SCHAR)scale;
   1215 
   1216     doScaleNrg = 1;
   1217   }
   1218   for (pb = startParamBand; pb < self->parameterBands; pb++) {
   1219     FIXP_DBL tmp1;
   1220     FIXP_DBL tmp2;
   1221     INT s;
   1222 
   1223     /* smoothDirRevNrg[2*pb  ] = fMult(smoothDirRevNrg[2*pb  ],DUCK_ALPHA_FDK) +
   1224        fMultDiv2(directNrg[pb],DUCK_ONE_MINUS_ALPHA_X4_FDK);
   1225        smoothDirRevNrg[2*pb+1] = fMult(smoothDirRevNrg[2*pb+1],DUCK_ALPHA_FDK) +
   1226        fMultDiv2(reverbNrg[pb],DUCK_ONE_MINUS_ALPHA_X4_FDK); tmp1 =
   1227        fMult(smoothDirRevNrg[2*pb],DUCK_GAMMA_FDK); tmp2 =
   1228        smoothDirRevNrg[2*pb+1] >> 1;
   1229     */
   1230     tmp1 = smoothDirRevNrg[2 * pb + 0];
   1231     tmp2 = smoothDirRevNrg[2 * pb + 1];
   1232     tmp1 = fMult(tmp1, DUCK_ALPHA_FDK);
   1233     tmp2 = fMult(tmp2, DUCK_ALPHA_FDK);
   1234 
   1235     if (doScaleNrg) {
   1236       int scaleSmoothDirRevNrg_asExponent = -scaleSmoothDirRevNrg;
   1237 
   1238       tmp1 = scaleValue(tmp1, scaleSmoothDirRevNrg_asExponent);
   1239       tmp2 = scaleValue(tmp2, scaleSmoothDirRevNrg_asExponent);
   1240       tmp1 = fMultAddDiv2(tmp1, directNrg[pb] >> scaleDirectNrg,
   1241                           DUCK_ONE_MINUS_ALPHA_X4_FDK);
   1242       tmp2 = fMultAddDiv2(tmp2, reverbNrg[pb] >> scaleReverbNrg,
   1243                           DUCK_ONE_MINUS_ALPHA_X4_FDK);
   1244     } else {
   1245       tmp1 = fMultAddDiv2(tmp1, directNrg[pb], DUCK_ONE_MINUS_ALPHA_X4_FDK);
   1246       tmp2 = fMultAddDiv2(tmp2, reverbNrg[pb], DUCK_ONE_MINUS_ALPHA_X4_FDK);
   1247     }
   1248 
   1249     smoothDirRevNrg[2 * pb] = tmp1;
   1250     smoothDirRevNrg[2 * pb + 1] = tmp2;
   1251 
   1252     maxDirRevNrg |= fAbs(tmp1);
   1253     maxDirRevNrg |= fAbs(tmp2);
   1254 
   1255     tmp1 = fMult(tmp1, DUCK_GAMMA_FDK);
   1256     tmp2 = tmp2 >> 1;
   1257 
   1258     qs_next = fMin((int)self->qs_next[pb], self->hybridBands);
   1259 
   1260     if (tmp2 > tmp1) { /* true for about 20% */
   1261       /* gain smaller than 1.0 */
   1262       tmp1 = sqrtFixp(tmp1);
   1263       tmp2 = invSqrtNorm2(tmp2, &s);
   1264       duckGain = FX_DBL2FX_DUCK_GAIN(fMultDiv2(tmp1, tmp2) << s);
   1265     } else { /* true for about 80 % */
   1266       tmp2 = smoothDirRevNrg[2 * pb] >> 1;
   1267       tmp1 = fMult(smoothDirRevNrg[2 * pb + 1], DUCK_GAMMA_FDK);
   1268       if (tmp2 > tmp1) { /* true for about 20% */
   1269         if (tmp1 <= (tmp2 >> 2)) {
   1270           /* limit gain to 2.0 */
   1271           if (qs < hybBands) {
   1272             for (; qs < qs_next; qs++) {
   1273               outputReal[qs] = outputReal[qs] << 1;
   1274               outputImag[qs] = outputImag[qs] << 1;
   1275             }
   1276           } else {
   1277             for (; qs < qs_next; qs++) {
   1278               outputReal[qs] = outputReal[qs] << 1;
   1279             }
   1280           }
   1281           /* skip general gain*output section */
   1282           continue;
   1283         } else {
   1284           /* gain from 1.0 to 2.0 */
   1285           tmp2 = sqrtFixp(tmp2 >> 2);
   1286           tmp1 = invSqrtNorm2(tmp1, &s);
   1287           duckGain = FX_DBL2FX_DUCK_GAIN(fMult(tmp1, tmp2) << s);
   1288         }
   1289       } else { /* true for about 60% */
   1290         /* gain = 1.0; output does not change; update qs index */
   1291         qs = qs_next;
   1292         continue;
   1293       }
   1294     }
   1295 
   1296 #ifdef FUNCTION_DuckerApply_func1
   1297     qs = DuckerApply_func1(qs, hybBands, qs_next, outputReal, outputImag,
   1298                            duckGain);
   1299 #else
   1300     /* general gain*output section */
   1301     if (qs < hybBands) {           /* true for about 39% */
   1302       for (; qs < qs_next; qs++) { /* runs about 2 times */
   1303         outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
   1304         outputImag[qs] = fMultDiv2(outputImag[qs], duckGain) << 2;
   1305       }
   1306     } else {
   1307       for (; qs < qs_next; qs++) {
   1308         outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
   1309       }
   1310     }
   1311 #endif
   1312   } /* pb */
   1313 
   1314   self->headroomSmoothDirRevNrg =
   1315       (SCHAR)fixMax(0, CntLeadingZeros(maxDirRevNrg) - 1);
   1316 
   1317   C_ALLOC_SCRATCH_END(reverbNrg, FIXP_DBL, (28));
   1318 
   1319   return err;
   1320 }
   1321 
   1322 LNK_SECTION_CODE_L1
   1323 static INT DuckerApplyPS(DUCKER_INSTANCE *const self,
   1324                          FIXP_DBL const directNrg[(28)],
   1325                          FIXP_DBL outputReal[(71)], FIXP_DBL outputImag[(71)],
   1326                          int startHybBand) {
   1327   int qs = startHybBand;
   1328   int pb = 0;
   1329   int startParamBand =
   1330       SpatialDecGetProcessingBand(startHybBand, self->mapHybBands2ProcBands);
   1331   int hybBands;
   1332 
   1333   int doScaleNrg = 0;
   1334   int scaleDirectNrg = 0;
   1335   int scaleSmoothDirRevNrg = 0;
   1336   FIXP_DBL maxDirRevNrg = FL2FXCONST_DBL(0.0);
   1337 
   1338   if ((self->scaleDirectNrg != self->scaleSmoothDirRevNrg) ||
   1339       (self->headroomSmoothDirRevNrg == 0)) {
   1340     int scale;
   1341 
   1342     scale = fixMin(self->scaleDirectNrg, self->scaleSmoothDirRevNrg +
   1343                                              self->headroomSmoothDirRevNrg - 2);
   1344 
   1345     scaleDirectNrg = fMax(fMin(self->scaleDirectNrg - scale, (DFRACT_BITS - 1)),
   1346                           -(DFRACT_BITS - 1));
   1347     scaleSmoothDirRevNrg =
   1348         fMax(fMin(self->scaleSmoothDirRevNrg - scale, (DFRACT_BITS - 1)),
   1349              -(DFRACT_BITS - 1));
   1350 
   1351     self->scaleSmoothDirRevNrg = (SCHAR)scale;
   1352 
   1353     doScaleNrg = 1;
   1354   }
   1355 
   1356   hybBands = self->hybridBands;
   1357 
   1358   FDK_ASSERT((self->parameterBands == (28)) || (self->parameterBands == (20)));
   1359   for (pb = startParamBand; pb < self->parameterBands; pb++) {
   1360     FIXP_DBL directNrg2 = directNrg[pb];
   1361 
   1362     if (doScaleNrg) {
   1363       directNrg2 = scaleValue(directNrg2, -scaleDirectNrg);
   1364       self->peakDiff[pb] =
   1365           scaleValue(self->peakDiff[pb], -scaleSmoothDirRevNrg);
   1366       self->peakDecay[pb] =
   1367           scaleValue(self->peakDecay[pb], -scaleSmoothDirRevNrg);
   1368       self->SmoothDirRevNrg[pb] =
   1369           scaleValue(self->SmoothDirRevNrg[pb], -scaleSmoothDirRevNrg);
   1370     }
   1371     self->peakDecay[pb] = fixMax(
   1372         directNrg2, fMult(self->peakDecay[pb], PS_DUCK_PEAK_DECAY_FACTOR_FDK));
   1373     self->peakDiff[pb] =
   1374         self->peakDiff[pb] +
   1375         fMult(PS_DUCK_FILTER_COEFF_FDK,
   1376               (self->peakDecay[pb] - directNrg2 - self->peakDiff[pb]));
   1377     self->SmoothDirRevNrg[pb] =
   1378         fixMax(self->SmoothDirRevNrg[pb] +
   1379                    fMult(PS_DUCK_FILTER_COEFF_FDK,
   1380                          (directNrg2 - self->SmoothDirRevNrg[pb])),
   1381                FL2FXCONST_DBL(0));
   1382 
   1383     maxDirRevNrg |= fAbs(self->peakDiff[pb]);
   1384     maxDirRevNrg |= fAbs(self->SmoothDirRevNrg[pb]);
   1385 
   1386     if ((self->peakDiff[pb] == FL2FXCONST_DBL(0)) &&
   1387         (self->SmoothDirRevNrg[pb] == FL2FXCONST_DBL(0))) {
   1388       int qs_next;
   1389 
   1390       qs = fMax(qs, SpatialDecGetQmfBand(pb, self->mapProcBands2HybBands));
   1391       qs_next = fMin((int)self->qs_next[pb], self->hybridBands);
   1392 
   1393       FIXP_DBL *pOutputReal = &outputReal[qs];
   1394       FIXP_DBL *pOutputImag = &outputImag[qs];
   1395 
   1396       if (qs < hybBands) {
   1397         for (; qs < qs_next; qs++) {
   1398           *pOutputReal++ = FL2FXCONST_DBL(0);
   1399           *pOutputImag++ = FL2FXCONST_DBL(0);
   1400         }
   1401       } else {
   1402         for (; qs < qs_next; qs++) {
   1403           *pOutputReal++ = FL2FXCONST_DBL(0);
   1404         }
   1405       }
   1406     } else if (self->peakDiff[pb] != FL2FXCONST_DBL(0)) {
   1407       FIXP_DBL multiplication =
   1408           fMult(FL2FXCONST_DUCK(0.75f), self->peakDiff[pb]);
   1409       if (multiplication > (self->SmoothDirRevNrg[pb] >> 1)) {
   1410         FIXP_DBL num, denom, duckGain;
   1411         int scale, qs_next;
   1412 
   1413         /* implement x/y as (sqrt(x)*invSqrt(y))^2 */
   1414         num = sqrtFixp(self->SmoothDirRevNrg[pb] >> 1);
   1415         denom = self->peakDiff[pb] +
   1416                 FL2FXCONST_DBL(ABS_THR / (32768.0f * 32768.0f * 128.0f * 1.5f));
   1417         denom = invSqrtNorm2(denom, &scale);
   1418 
   1419         /* duck output whether duckGain != 1.f */
   1420         qs = fMax(qs, SpatialDecGetQmfBand(pb, self->mapProcBands2HybBands));
   1421         qs_next = fMin((int)self->qs_next[pb], self->hybridBands);
   1422 
   1423         duckGain = fMult(num, denom);
   1424         duckGain = fPow2Div2(duckGain << scale);
   1425         duckGain = fMultDiv2(FL2FXCONST_DUCK(2.f / 3.f), duckGain) << 3;
   1426 
   1427         FIXP_DBL *pOutputReal = &outputReal[qs];
   1428         FIXP_DBL *pOutputImag = &outputImag[qs];
   1429 
   1430         if (qs < hybBands) {
   1431           for (; qs < qs_next; qs++) {
   1432             *pOutputReal = fMult(*pOutputReal, duckGain);
   1433             pOutputReal++; /* don't move in front of "=" above, because then the
   1434                               fract class treats it differently and provides
   1435                               wrong argument to fMult() (seen on win32/msvc8) */
   1436             *pOutputImag = fMult(*pOutputImag, duckGain);
   1437             pOutputImag++;
   1438           }
   1439         } else {
   1440           for (; qs < qs_next; qs++) {
   1441             *pOutputReal = fMult(*pOutputReal, duckGain);
   1442             pOutputReal++;
   1443           }
   1444         }
   1445       }
   1446     }
   1447   } /* pb */
   1448 
   1449   self->headroomSmoothDirRevNrg =
   1450       (SCHAR)fixMax(0, CntLeadingZeros(maxDirRevNrg) - 1);
   1451 
   1452   return 0;
   1453 }
   1454 
   1455 INT FDKdecorrelateOpen(HANDLE_DECORR_DEC hDecorrDec, FIXP_DBL *bufferCplx,
   1456                        const INT bufLen) {
   1457   HANDLE_DECORR_DEC self = hDecorrDec;
   1458 
   1459   if (bufLen < (2 * ((825) + (373)))) return 1;
   1460 
   1461   /* assign all memory to stateBufferCplx. It is reassigned during
   1462    * FDKdecorrelateInit() */
   1463   self->stateBufferCplx = bufferCplx;
   1464   self->L_stateBufferCplx = 0;
   1465 
   1466   self->delayBufferCplx = NULL;
   1467   self->L_delayBufferCplx = 0;
   1468 
   1469   return 0;
   1470 }
   1471 
   1472 static int distributeBuffer(HANDLE_DECORR_DEC self, const int L_stateBuf,
   1473                             const int L_delayBuf) {
   1474   /* factor 2 because of complex values */
   1475   if ((2 * ((825) + (373))) < 2 * (L_stateBuf + L_delayBuf)) {
   1476     return 1;
   1477   }
   1478 
   1479   self->L_stateBufferCplx = 2 * L_stateBuf;
   1480   self->delayBufferCplx = self->stateBufferCplx + 2 * L_stateBuf;
   1481   self->L_delayBufferCplx = 2 * L_delayBuf;
   1482 
   1483   return 0;
   1484 }
   1485 INT FDKdecorrelateInit(HANDLE_DECORR_DEC hDecorrDec, const INT nrHybBands,
   1486                        const FDK_DECORR_TYPE decorrType,
   1487                        const FDK_DUCKER_TYPE duckerType, const INT decorrConfig,
   1488                        const INT seed, const INT partiallyComplex,
   1489                        const INT useFractDelay, const INT isLegacyPS,
   1490                        const INT initStatesFlag) {
   1491   INT errorCode = 0;
   1492   int i, rb, i_start;
   1493   int nParamBands = 28;
   1494 
   1495   INT offsetStateBuffer = 0;
   1496   INT offsetDelayBuffer = 0;
   1497 
   1498   const UCHAR *REV_bandOffset;
   1499 
   1500   const SCHAR *REV_filterOrder;
   1501 
   1502   hDecorrDec->partiallyComplex = partiallyComplex;
   1503   hDecorrDec->numbins = nrHybBands;
   1504 
   1505   switch (decorrType) {
   1506     case DECORR_PS:
   1507       /* ignore decorrConfig, seed */
   1508       if (partiallyComplex) {
   1509         hDecorrDec->REV_bandOffset = REV_bandOffset_PS_LP;
   1510         hDecorrDec->REV_delay = REV_delay_PS_LP;
   1511         errorCode = distributeBuffer(hDecorrDec, (168), (533));
   1512       } else {
   1513         hDecorrDec->REV_bandOffset = REV_bandOffset_PS_HQ;
   1514         hDecorrDec->REV_delay = REV_delay_PS_HQ;
   1515         errorCode = distributeBuffer(hDecorrDec, (360), (257));
   1516       }
   1517       hDecorrDec->REV_filterOrder = REV_filterOrder_PS;
   1518       hDecorrDec->REV_filtType = REV_filtType_PS;
   1519 
   1520       /* Initialize ring buffer offsets for PS specific filter implementation.
   1521        */
   1522       for (i = 0; i < (3); i++)
   1523         hDecorrDec->stateBufferOffset[i] = stateBufferOffsetInit[i];
   1524 
   1525       break;
   1526     case DECORR_USAC:
   1527       if (partiallyComplex) return 1;
   1528       if (seed != 0) return 1;
   1529       hDecorrDec->REV_bandOffset =
   1530           REV_bandOffset_MPS_HQ[decorrConfig]; /* reverb band layout is
   1531                                                   inherited from MPS standard */
   1532       hDecorrDec->REV_filterOrder = REV_filterOrder_USAC;
   1533       hDecorrDec->REV_delay = REV_delay_USAC;
   1534       if (useFractDelay) {
   1535         return 1; /* not yet supported */
   1536       } else {
   1537         hDecorrDec->REV_filtType = REV_filtType_MPS; /* the filter types are
   1538                                                         inherited from MPS
   1539                                                         standard */
   1540       }
   1541       /* bsDecorrConfig == 1 is worst case */
   1542       errorCode = distributeBuffer(hDecorrDec, (509), (643));
   1543       break;
   1544     case DECORR_LD:
   1545       if (partiallyComplex) return 1;
   1546       if (useFractDelay) return 1;
   1547       if (decorrConfig > 2) return 1;
   1548       if (seed > (MAX_DECORR_SEED_LD - 1)) return 1;
   1549       if (!(nrHybBands == 64 || nrHybBands == 32))
   1550         return 1; /* actually just qmf bands and no hybrid bands */
   1551       hDecorrDec->REV_bandOffset = REV_bandOffset_LD[decorrConfig];
   1552       hDecorrDec->REV_filterOrder = REV_filterOrder_MPS; /* the filter orders
   1553                                                             are inherited from
   1554                                                             MPS standard */
   1555       hDecorrDec->REV_delay =
   1556           REV_delay_MPS; /* the delays in each reverb band are inherited from
   1557                             MPS standard */
   1558       hDecorrDec->REV_filtType = REV_filtType_LD;
   1559       errorCode = distributeBuffer(hDecorrDec, (825), (373));
   1560       break;
   1561     default:
   1562       return 1;
   1563   }
   1564 
   1565   if (errorCode) {
   1566     return errorCode;
   1567   }
   1568 
   1569   if (initStatesFlag) {
   1570     FDKmemclear(
   1571         hDecorrDec->stateBufferCplx,
   1572         hDecorrDec->L_stateBufferCplx * sizeof(*hDecorrDec->stateBufferCplx));
   1573     FDKmemclear(
   1574         hDecorrDec->delayBufferCplx,
   1575         hDecorrDec->L_delayBufferCplx * sizeof(*hDecorrDec->delayBufferCplx));
   1576     FDKmemclear(hDecorrDec->reverbBandDelayBufferIndex,
   1577                 sizeof(hDecorrDec->reverbBandDelayBufferIndex));
   1578   }
   1579 
   1580   REV_bandOffset = hDecorrDec->REV_bandOffset;
   1581 
   1582   REV_filterOrder = hDecorrDec->REV_filterOrder;
   1583 
   1584   i_start = 0;
   1585   for (rb = 0; rb < (4); rb++) {
   1586     int i_stop;
   1587 
   1588     i_stop = REV_bandOffset[rb];
   1589 
   1590     if (i_stop <= i_start) {
   1591       continue;
   1592     }
   1593 
   1594     for (i = i_start; i < i_stop; i++) {
   1595       switch (decorrType) {
   1596         case DECORR_PS:
   1597           errorCode = DecorrFilterInitPS(
   1598               &hDecorrDec->Filter[i], hDecorrDec->stateBufferCplx,
   1599               hDecorrDec->delayBufferCplx, &offsetStateBuffer,
   1600               &offsetDelayBuffer, i, rb, hDecorrDec->REV_delay[rb]);
   1601           break;
   1602         default:
   1603           errorCode = DecorrFilterInit(
   1604               &hDecorrDec->Filter[i], hDecorrDec->stateBufferCplx,
   1605               hDecorrDec->delayBufferCplx, &offsetStateBuffer,
   1606               &offsetDelayBuffer, seed, rb, useFractDelay,
   1607               hDecorrDec->REV_delay[rb], REV_filterOrder[rb], decorrType);
   1608           break;
   1609       }
   1610     }
   1611 
   1612     i_start = i_stop;
   1613   } /* loop over reverbBands */
   1614 
   1615   if (!(offsetStateBuffer <= hDecorrDec->L_stateBufferCplx) ||
   1616       !(offsetDelayBuffer <= hDecorrDec->L_delayBufferCplx)) {
   1617     return errorCode = 1;
   1618   }
   1619 
   1620   if (duckerType == DUCKER_AUTOMATIC) {
   1621     /* Choose correct ducker type according to standards: */
   1622     switch (decorrType) {
   1623       case DECORR_PS:
   1624         hDecorrDec->ducker.duckerType = DUCKER_PS;
   1625         if (isLegacyPS) {
   1626           nParamBands = (20);
   1627         } else {
   1628           nParamBands = (28);
   1629         }
   1630         break;
   1631       case DECORR_USAC:
   1632         hDecorrDec->ducker.duckerType = DUCKER_MPS;
   1633         nParamBands = (28);
   1634         break;
   1635       case DECORR_LD:
   1636         hDecorrDec->ducker.duckerType = DUCKER_MPS;
   1637         nParamBands = (23);
   1638         break;
   1639       default:
   1640         return 1;
   1641     }
   1642   }
   1643 
   1644   errorCode = DuckerInit(
   1645       &hDecorrDec->ducker, hDecorrDec->numbins, hDecorrDec->partiallyComplex,
   1646       hDecorrDec->ducker.duckerType, nParamBands, initStatesFlag);
   1647 
   1648   return errorCode;
   1649 }
   1650 
   1651 INT FDKdecorrelateClose(HANDLE_DECORR_DEC hDecorrDec) {
   1652   INT err = 0;
   1653 
   1654   if (hDecorrDec == NULL) {
   1655     return 1;
   1656   }
   1657 
   1658   hDecorrDec->stateBufferCplx = NULL;
   1659   hDecorrDec->L_stateBufferCplx = 0;
   1660   hDecorrDec->delayBufferCplx = NULL;
   1661   hDecorrDec->L_delayBufferCplx = 0;
   1662 
   1663   return err;
   1664 }
   1665 
   1666 LNK_SECTION_CODE_L1
   1667 INT FDKdecorrelateApply(HANDLE_DECORR_DEC hDecorrDec, FIXP_DBL *dataRealIn,
   1668                         FIXP_DBL *dataImagIn, FIXP_DBL *dataRealOut,
   1669                         FIXP_DBL *dataImagOut, const INT startHybBand) {
   1670   HANDLE_DECORR_DEC self = hDecorrDec;
   1671   INT err = 0;
   1672   INT rb, stop, start;
   1673 
   1674   if (self != NULL) {
   1675     int nHybBands = 0;
   1676     /* copy new samples */
   1677     nHybBands = self->numbins;
   1678 
   1679     FIXP_DBL directNrg[(28)];
   1680 
   1681     DuckerCalcEnergy(
   1682         &self->ducker, dataRealIn, dataImagIn, directNrg,
   1683         self->ducker.maxValDirectData, &(self->ducker.scaleDirectNrg),
   1684         (self->ducker.duckerType == DUCKER_PS) ? 1 : 0, startHybBand);
   1685 
   1686     /* complex-valued hybrid bands */
   1687     for (stop = 0, rb = 0; rb < (4); rb++) {
   1688       start = fMax(stop, startHybBand);
   1689       stop = fMin(self->REV_bandOffset[rb], (UCHAR)nHybBands);
   1690 
   1691       if (start < stop) {
   1692         switch (hDecorrDec->REV_filtType[rb]) {
   1693           case DELAY:
   1694             err = DecorrFilterApplyPASS(&self->Filter[0], dataRealIn,
   1695                                         dataImagIn, dataRealOut, dataImagOut,
   1696                                         start, stop, self->REV_delay[rb],
   1697                                         self->reverbBandDelayBufferIndex[rb]);
   1698             break;
   1699           case INDEP_CPLX_PS:
   1700             err = DecorrFilterApplyCPLX_PS(
   1701                 &self->Filter[0], dataRealIn, dataImagIn, dataRealOut,
   1702                 dataImagOut, start, stop, self->REV_filterOrder[rb],
   1703                 self->REV_delay[rb], self->reverbBandDelayBufferIndex[rb],
   1704                 self->stateBufferOffset);
   1705             break;
   1706           case COMMON_REAL:
   1707             err = DecorrFilterApplyREAL(
   1708                 &self->Filter[0], dataRealIn, dataImagIn, dataRealOut,
   1709                 dataImagOut, start, stop, self->REV_filterOrder[rb],
   1710                 self->REV_delay[rb], self->reverbBandDelayBufferIndex[rb]);
   1711             break;
   1712           default:
   1713             err = 1;
   1714             break;
   1715         }
   1716         if (err != 0) {
   1717           goto bail;
   1718         }
   1719       } /* if start < stop */
   1720     }   /* loop over reverb bands */
   1721 
   1722     for (rb = 0; rb < (4); rb++) {
   1723       self->reverbBandDelayBufferIndex[rb] += 2;
   1724       if (self->reverbBandDelayBufferIndex[rb] >= 2 * self->REV_delay[rb])
   1725         self->reverbBandDelayBufferIndex[rb] = 0;
   1726     }
   1727 
   1728     switch (self->ducker.duckerType) {
   1729       case DUCKER_PS:
   1730         err = DuckerApplyPS(&self->ducker, directNrg, dataRealOut, dataImagOut,
   1731                             startHybBand);
   1732         if (err != 0) goto bail;
   1733         break;
   1734       default:
   1735         err = DuckerApply(&self->ducker, directNrg, dataRealOut, dataImagOut,
   1736                           startHybBand);
   1737         if (err != 0) goto bail;
   1738         break;
   1739     }
   1740   }
   1741 
   1742 bail:
   1743   return err;
   1744 }
   1745