• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung 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@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 
SpatialDecGetProcessingBand(int hybridBand,const UCHAR * tab)219 static inline int SpatialDecGetProcessingBand(int hybridBand,
220                                               const UCHAR *tab) {
221   return tab[hybridBand];
222 }
223 
224 /* helper inline function */
SpatialDecGetQmfBand(int paramBand,const UCHAR * tab)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 
getAddrDirectSignalMaxVal(HANDLE_DECORR_DEC self)490 FIXP_DBL *getAddrDirectSignalMaxVal(HANDLE_DECORR_DEC self) {
491   return &(self->ducker.maxValDirectData);
492 }
493 
DecorrFilterInit(DECORR_FILTER_INSTANCE * const self,FIXP_MPS * pStateBufferCplx,FIXP_DBL * pDelayBufferCplx,INT * offsetStateBuffer,INT * offsetDelayBuffer,INT const decorr_seed,INT const reverb_band,INT const useFractDelay,INT const noSampleDelay,INT const filterOrder,FDK_DECORR_TYPE const decorrType)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 *******************************************************************************/
DecorrFilterInitPS(DECORR_FILTER_INSTANCE * const self,FIXP_MPS * pStateBufferCplx,FIXP_DBL * pDelayBufferCplx,INT * offsetStateBuffer,INT * offsetDelayBuffer,INT const hybridBand,INT const reverbBand,INT const noSampleDelay)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
DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],FIXP_DBL * dataRealIn,FIXP_DBL * dataImagIn,FIXP_DBL * dataRealOut,FIXP_DBL * dataImagOut,INT start,INT stop,INT reverbBandNoSampleDelay,INT reverbBandDelayBufferIndex)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
DecorrFilterApplyREAL(DECORR_FILTER_INSTANCE const filter[],FIXP_DBL * dataRealIn,FIXP_DBL * dataImagIn,FIXP_DBL * dataRealOut,FIXP_DBL * dataImagOut,INT start,INT stop,INT reverbFilterOrder,INT reverbBandNoSampleDelay,INT reverbBandDelayBufferIndex)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
DecorrFilterApplyCPLX_PS(DECORR_FILTER_INSTANCE const filter[],FIXP_DBL * dataRealIn,FIXP_DBL * dataImagIn,FIXP_DBL * dataRealOut,FIXP_DBL * dataImagOut,INT start,INT stop,INT reverbFilterOrder,INT reverbBandNoSampleDelay,INT reverbBandDelayBufferIndex,UCHAR * stateBufferOffset)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 *******************************************************************************/
DuckerInit(DUCKER_INSTANCE * const self,int const hybridBands,int partiallyComplex,const FDK_DUCKER_TYPE duckerType,const int nParamBands,int initStatesFlag)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
DuckerCalcEnergy(DUCKER_INSTANCE * const self,FIXP_DBL const inputReal[(71)],FIXP_DBL const inputImag[(71)],FIXP_DBL energy[(28)],FIXP_DBL inputMaxVal,SCHAR * nrgScale,int mode,int startHybBand)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           fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
1091                                        fPow2Div2(inputImag[qs] << clz));
1092     }
1093     pb++;
1094 
1095     for (; pb <= SpatialDecGetProcessingBand(maxHybridBand,
1096                                              self->mapHybBands2ProcBands);
1097          pb++) {
1098       FDK_ASSERT(pb != SpatialDecGetProcessingBand(
1099                            qs - 1, self->mapHybBands2ProcBands));
1100       int qs_next;
1101       FIXP_DBL nrg = 0;
1102       qs_next = (int)self->qs_next[pb];
1103       for (; qs < qs_next; qs++) {
1104         nrg = fAddSaturate(nrg, fPow2Div2(inputReal[qs] << clz));
1105       }
1106       energy[pb] = nrg;
1107     }
1108   } else {
1109     int clz;
1110     FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
1111 
1112     maxVal = inputMaxVal;
1113 
1114     if (maxVal == FL2FXCONST_DBL(-1.0f)) {
1115 #ifdef FUNCTION_DuckerCalcEnergy_func2
1116       maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
1117                                       maxHybBand, maxHybridBand);
1118 #else
1119       FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
1120       for (qs = startHybBand; qs <= maxHybBand; qs++) {
1121         localMaxVal |= fAbs(inputReal[qs]);
1122         localMaxVal |= fAbs(inputImag[qs]);
1123       }
1124       for (; qs <= maxHybridBand; qs++) {
1125         localMaxVal |= fAbs(inputReal[qs]);
1126       }
1127       maxVal = localMaxVal;
1128 #endif
1129     }
1130 
1131     clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
1132     clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
1133     *nrgScale = (SCHAR)clz << 1;
1134 
1135 #ifdef FUNCTION_DuckerCalcEnergy_func4
1136     DuckerCalcEnergy_func4(inputReal, inputImag, energy,
1137                            self->mapHybBands2ProcBands, clz, startHybBand,
1138                            maxHybBand, maxHybridBand);
1139 #else
1140     for (qs = startHybBand; qs <= maxHybBand; qs++) {
1141       int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
1142       energy[pb] =
1143           fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
1144                                        fPow2Div2(inputImag[qs] << clz));
1145     }
1146 
1147     for (; qs <= maxHybridBand; qs++) {
1148       int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
1149       energy[pb] = fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz));
1150     }
1151 #endif /* FUNCTION_DuckerCalcEnergy_func4 */
1152   }
1153 
1154   {
1155     /* Catch overflows which have been observed in erred bitstreams to avoid
1156      * assertion failures later. */
1157     int pb;
1158     for (pb = 0; pb < (28); pb++) {
1159       energy[pb] = (FIXP_DBL)((LONG)energy[pb] & (LONG)MAXVAL_DBL);
1160     }
1161   }
1162   return err;
1163 }
1164 #endif /* #ifndef FUNCTION_DuckerCalcEnergy */
1165 
1166 LNK_SECTION_CODE_L1
DuckerApply(DUCKER_INSTANCE * const self,FIXP_DBL const directNrg[(28)],FIXP_DBL outputReal[(71)],FIXP_DBL outputImag[(71)],int startHybBand)1167 static INT DuckerApply(DUCKER_INSTANCE *const self,
1168                        FIXP_DBL const directNrg[(28)],
1169                        FIXP_DBL outputReal[(71)], FIXP_DBL outputImag[(71)],
1170                        int startHybBand) {
1171   INT err = 0;
1172   int qs = startHybBand;
1173   int qs_next = 0;
1174   int pb = 0;
1175   int startParamBand = 0;
1176   int hybBands;
1177   int hybridBands = self->hybridBands;
1178 
1179   C_ALLOC_SCRATCH_START(reverbNrg, FIXP_DBL, (28));
1180 
1181   FIXP_DBL *smoothDirRevNrg = &self->SmoothDirRevNrg[0];
1182   FIXP_DUCK_GAIN duckGain = 0;
1183 
1184   int doScaleNrg = 0;
1185   int scaleDirectNrg = 0;
1186   int scaleReverbNrg = 0;
1187   int scaleSmoothDirRevNrg = 0;
1188   FIXP_DBL maxDirRevNrg = FL2FXCONST_DBL(0.0);
1189 
1190   hybBands = hybridBands;
1191 
1192   startParamBand =
1193       SpatialDecGetProcessingBand(startHybBand, self->mapHybBands2ProcBands);
1194 
1195   DuckerCalcEnergy(self, outputReal, outputImag, reverbNrg,
1196                    self->maxValReverbData, &(self->scaleReverbNrg), 0,
1197                    startHybBand);
1198 
1199   if ((self->scaleDirectNrg != self->scaleReverbNrg) ||
1200       (self->scaleDirectNrg != self->scaleSmoothDirRevNrg) ||
1201       (self->headroomSmoothDirRevNrg == 0)) {
1202     int scale;
1203 
1204     scale = fixMin(self->scaleDirectNrg, self->scaleSmoothDirRevNrg +
1205                                              self->headroomSmoothDirRevNrg - 1);
1206     scale = fixMin(scale, self->scaleReverbNrg);
1207 
1208     scaleDirectNrg = fMax(fMin(self->scaleDirectNrg - scale, (DFRACT_BITS - 1)),
1209                           -(DFRACT_BITS - 1));
1210     scaleReverbNrg = fMax(fMin(self->scaleReverbNrg - scale, (DFRACT_BITS - 1)),
1211                           -(DFRACT_BITS - 1));
1212     scaleSmoothDirRevNrg =
1213         fMax(fMin(self->scaleSmoothDirRevNrg - scale, (DFRACT_BITS - 1)),
1214              -(DFRACT_BITS - 1));
1215 
1216     self->scaleSmoothDirRevNrg = (SCHAR)scale;
1217 
1218     doScaleNrg = 1;
1219   }
1220   for (pb = startParamBand; pb < self->parameterBands; pb++) {
1221     FIXP_DBL tmp1;
1222     FIXP_DBL tmp2;
1223     INT s;
1224 
1225     /* smoothDirRevNrg[2*pb  ] = fMult(smoothDirRevNrg[2*pb  ],DUCK_ALPHA_FDK) +
1226        fMultDiv2(directNrg[pb],DUCK_ONE_MINUS_ALPHA_X4_FDK);
1227        smoothDirRevNrg[2*pb+1] = fMult(smoothDirRevNrg[2*pb+1],DUCK_ALPHA_FDK) +
1228        fMultDiv2(reverbNrg[pb],DUCK_ONE_MINUS_ALPHA_X4_FDK); tmp1 =
1229        fMult(smoothDirRevNrg[2*pb],DUCK_GAMMA_FDK); tmp2 =
1230        smoothDirRevNrg[2*pb+1] >> 1;
1231     */
1232     tmp1 = smoothDirRevNrg[2 * pb + 0];
1233     tmp2 = smoothDirRevNrg[2 * pb + 1];
1234     tmp1 = fMult(tmp1, DUCK_ALPHA_FDK);
1235     tmp2 = fMult(tmp2, DUCK_ALPHA_FDK);
1236 
1237     if (doScaleNrg) {
1238       int scaleSmoothDirRevNrg_asExponent = -scaleSmoothDirRevNrg;
1239 
1240       tmp1 = scaleValue(tmp1, scaleSmoothDirRevNrg_asExponent);
1241       tmp2 = scaleValue(tmp2, scaleSmoothDirRevNrg_asExponent);
1242       tmp1 = fMultAddDiv2(tmp1, scaleValue(directNrg[pb], -scaleDirectNrg),
1243                           DUCK_ONE_MINUS_ALPHA_X4_FDK);
1244       tmp2 = fMultAddDiv2(tmp2, scaleValue(reverbNrg[pb], -scaleReverbNrg),
1245                           DUCK_ONE_MINUS_ALPHA_X4_FDK);
1246     } else {
1247       tmp1 = fMultAddDiv2(tmp1, directNrg[pb], DUCK_ONE_MINUS_ALPHA_X4_FDK);
1248       tmp2 = fMultAddDiv2(tmp2, reverbNrg[pb], DUCK_ONE_MINUS_ALPHA_X4_FDK);
1249     }
1250 
1251     smoothDirRevNrg[2 * pb] = tmp1;
1252     smoothDirRevNrg[2 * pb + 1] = tmp2;
1253 
1254     maxDirRevNrg |= fAbs(tmp1);
1255     maxDirRevNrg |= fAbs(tmp2);
1256 
1257     tmp1 = fMult(tmp1, DUCK_GAMMA_FDK);
1258     tmp2 = tmp2 >> 1;
1259 
1260     qs_next = fMin((int)self->qs_next[pb], self->hybridBands);
1261 
1262     if (tmp2 > tmp1) { /* true for about 20% */
1263       /* gain smaller than 1.0 */
1264       tmp1 = sqrtFixp(tmp1);
1265       tmp2 = invSqrtNorm2(tmp2, &s);
1266       duckGain = FX_DBL2FX_DUCK_GAIN(fMultDiv2(tmp1, tmp2) << s);
1267     } else { /* true for about 80 % */
1268       tmp2 = smoothDirRevNrg[2 * pb] >> 1;
1269       tmp1 = fMult(smoothDirRevNrg[2 * pb + 1], DUCK_GAMMA_FDK);
1270       if (tmp2 > tmp1) { /* true for about 20% */
1271         if (tmp1 <= (tmp2 >> 2)) {
1272           /* limit gain to 2.0 */
1273           if (qs < hybBands) {
1274             for (; qs < qs_next; qs++) {
1275               outputReal[qs] = outputReal[qs] << 1;
1276               outputImag[qs] = outputImag[qs] << 1;
1277             }
1278           } else {
1279             for (; qs < qs_next; qs++) {
1280               outputReal[qs] = outputReal[qs] << 1;
1281             }
1282           }
1283           /* skip general gain*output section */
1284           continue;
1285         } else {
1286           /* gain from 1.0 to 2.0 */
1287           tmp2 = sqrtFixp(tmp2 >> 2);
1288           tmp1 = invSqrtNorm2(tmp1, &s);
1289           duckGain = FX_DBL2FX_DUCK_GAIN(fMult(tmp1, tmp2) << s);
1290         }
1291       } else { /* true for about 60% */
1292         /* gain = 1.0; output does not change; update qs index */
1293         qs = qs_next;
1294         continue;
1295       }
1296     }
1297 
1298 #ifdef FUNCTION_DuckerApply_func1
1299     qs = DuckerApply_func1(qs, hybBands, qs_next, outputReal, outputImag,
1300                            duckGain);
1301 #else
1302     /* general gain*output section */
1303     if (qs < hybBands) {           /* true for about 39% */
1304       for (; qs < qs_next; qs++) { /* runs about 2 times */
1305         outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
1306         outputImag[qs] = fMultDiv2(outputImag[qs], duckGain) << 2;
1307       }
1308     } else {
1309       for (; qs < qs_next; qs++) {
1310         outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
1311       }
1312     }
1313 #endif
1314   } /* pb */
1315 
1316   self->headroomSmoothDirRevNrg =
1317       (SCHAR)fixMax(0, CntLeadingZeros(maxDirRevNrg) - 1);
1318 
1319   C_ALLOC_SCRATCH_END(reverbNrg, FIXP_DBL, (28));
1320 
1321   return err;
1322 }
1323 
1324 LNK_SECTION_CODE_L1
DuckerApplyPS(DUCKER_INSTANCE * const self,FIXP_DBL const directNrg[(28)],FIXP_DBL outputReal[(71)],FIXP_DBL outputImag[(71)],int startHybBand)1325 static INT DuckerApplyPS(DUCKER_INSTANCE *const self,
1326                          FIXP_DBL const directNrg[(28)],
1327                          FIXP_DBL outputReal[(71)], FIXP_DBL outputImag[(71)],
1328                          int startHybBand) {
1329   int qs = startHybBand;
1330   int pb = 0;
1331   int startParamBand =
1332       SpatialDecGetProcessingBand(startHybBand, self->mapHybBands2ProcBands);
1333   int hybBands;
1334 
1335   int doScaleNrg = 0;
1336   int scaleDirectNrg = 0;
1337   int scaleSmoothDirRevNrg = 0;
1338   FIXP_DBL maxDirRevNrg = FL2FXCONST_DBL(0.0);
1339 
1340   if ((self->scaleDirectNrg != self->scaleSmoothDirRevNrg) ||
1341       (self->headroomSmoothDirRevNrg == 0)) {
1342     int scale;
1343 
1344     scale = fixMin(self->scaleDirectNrg, self->scaleSmoothDirRevNrg +
1345                                              self->headroomSmoothDirRevNrg - 2);
1346 
1347     scaleDirectNrg = fMax(fMin(self->scaleDirectNrg - scale, (DFRACT_BITS - 1)),
1348                           -(DFRACT_BITS - 1));
1349     scaleSmoothDirRevNrg =
1350         fMax(fMin(self->scaleSmoothDirRevNrg - scale, (DFRACT_BITS - 1)),
1351              -(DFRACT_BITS - 1));
1352 
1353     self->scaleSmoothDirRevNrg = (SCHAR)scale;
1354 
1355     doScaleNrg = 1;
1356   }
1357 
1358   hybBands = self->hybridBands;
1359 
1360   FDK_ASSERT((self->parameterBands == (28)) || (self->parameterBands == (20)));
1361   for (pb = startParamBand; pb < self->parameterBands; pb++) {
1362     FIXP_DBL directNrg2 = directNrg[pb];
1363 
1364     if (doScaleNrg) {
1365       directNrg2 = scaleValue(directNrg2, -scaleDirectNrg);
1366       self->peakDiff[pb] =
1367           scaleValue(self->peakDiff[pb], -scaleSmoothDirRevNrg);
1368       self->peakDecay[pb] =
1369           scaleValue(self->peakDecay[pb], -scaleSmoothDirRevNrg);
1370       self->SmoothDirRevNrg[pb] =
1371           scaleValue(self->SmoothDirRevNrg[pb], -scaleSmoothDirRevNrg);
1372     }
1373     self->peakDecay[pb] = fixMax(
1374         directNrg2, fMult(self->peakDecay[pb], PS_DUCK_PEAK_DECAY_FACTOR_FDK));
1375     self->peakDiff[pb] =
1376         self->peakDiff[pb] +
1377         fMult(PS_DUCK_FILTER_COEFF_FDK,
1378               (self->peakDecay[pb] - directNrg2 - self->peakDiff[pb]));
1379     self->SmoothDirRevNrg[pb] =
1380         fixMax(self->SmoothDirRevNrg[pb] +
1381                    fMult(PS_DUCK_FILTER_COEFF_FDK,
1382                          (directNrg2 - self->SmoothDirRevNrg[pb])),
1383                FL2FXCONST_DBL(0));
1384 
1385     maxDirRevNrg |= fAbs(self->peakDiff[pb]);
1386     maxDirRevNrg |= fAbs(self->SmoothDirRevNrg[pb]);
1387 
1388     if ((self->peakDiff[pb] == FL2FXCONST_DBL(0)) &&
1389         (self->SmoothDirRevNrg[pb] == FL2FXCONST_DBL(0))) {
1390       int qs_next;
1391 
1392       qs = fMax(qs, SpatialDecGetQmfBand(pb, self->mapProcBands2HybBands));
1393       qs_next = fMin((int)self->qs_next[pb], self->hybridBands);
1394 
1395       FIXP_DBL *pOutputReal = &outputReal[qs];
1396       FIXP_DBL *pOutputImag = &outputImag[qs];
1397 
1398       if (qs < hybBands) {
1399         for (; qs < qs_next; qs++) {
1400           *pOutputReal++ = FL2FXCONST_DBL(0);
1401           *pOutputImag++ = FL2FXCONST_DBL(0);
1402         }
1403       } else {
1404         for (; qs < qs_next; qs++) {
1405           *pOutputReal++ = FL2FXCONST_DBL(0);
1406         }
1407       }
1408     } else if (self->peakDiff[pb] != FL2FXCONST_DBL(0)) {
1409       FIXP_DBL multiplication =
1410           fMult(FL2FXCONST_DUCK(0.75f), self->peakDiff[pb]);
1411       if (multiplication > (self->SmoothDirRevNrg[pb] >> 1)) {
1412         FIXP_DBL num, denom, duckGain;
1413         int scale, qs_next;
1414 
1415         /* implement x/y as (sqrt(x)*invSqrt(y))^2 */
1416         num = sqrtFixp(self->SmoothDirRevNrg[pb] >> 1);
1417         denom = self->peakDiff[pb] +
1418                 FL2FXCONST_DBL(ABS_THR / (32768.0f * 32768.0f * 128.0f * 1.5f));
1419         denom = invSqrtNorm2(denom, &scale);
1420 
1421         /* duck output whether duckGain != 1.f */
1422         qs = fMax(qs, SpatialDecGetQmfBand(pb, self->mapProcBands2HybBands));
1423         qs_next = fMin((int)self->qs_next[pb], self->hybridBands);
1424 
1425         duckGain = fMult(num, denom);
1426         duckGain = fPow2Div2(duckGain << scale);
1427         duckGain = fMultDiv2(FL2FXCONST_DUCK(2.f / 3.f), duckGain) << 3;
1428 
1429         FIXP_DBL *pOutputReal = &outputReal[qs];
1430         FIXP_DBL *pOutputImag = &outputImag[qs];
1431 
1432         if (qs < hybBands) {
1433           for (; qs < qs_next; qs++) {
1434             *pOutputReal = fMult(*pOutputReal, duckGain);
1435             pOutputReal++; /* don't move in front of "=" above, because then the
1436                               fract class treats it differently and provides
1437                               wrong argument to fMult() (seen on win32/msvc8) */
1438             *pOutputImag = fMult(*pOutputImag, duckGain);
1439             pOutputImag++;
1440           }
1441         } else {
1442           for (; qs < qs_next; qs++) {
1443             *pOutputReal = fMult(*pOutputReal, duckGain);
1444             pOutputReal++;
1445           }
1446         }
1447       }
1448     }
1449   } /* pb */
1450 
1451   self->headroomSmoothDirRevNrg =
1452       (SCHAR)fixMax(0, CntLeadingZeros(maxDirRevNrg) - 1);
1453 
1454   return 0;
1455 }
1456 
FDKdecorrelateOpen(HANDLE_DECORR_DEC hDecorrDec,FIXP_DBL * bufferCplx,const INT bufLen)1457 INT FDKdecorrelateOpen(HANDLE_DECORR_DEC hDecorrDec, FIXP_DBL *bufferCplx,
1458                        const INT bufLen) {
1459   HANDLE_DECORR_DEC self = hDecorrDec;
1460 
1461   if (bufLen < (2 * ((825) + (373)))) return 1;
1462 
1463   /* assign all memory to stateBufferCplx. It is reassigned during
1464    * FDKdecorrelateInit() */
1465   self->stateBufferCplx = bufferCplx;
1466   self->L_stateBufferCplx = 0;
1467 
1468   self->delayBufferCplx = NULL;
1469   self->L_delayBufferCplx = 0;
1470 
1471   return 0;
1472 }
1473 
distributeBuffer(HANDLE_DECORR_DEC self,const int L_stateBuf,const int L_delayBuf)1474 static int distributeBuffer(HANDLE_DECORR_DEC self, const int L_stateBuf,
1475                             const int L_delayBuf) {
1476   /* factor 2 because of complex values */
1477   if ((2 * ((825) + (373))) < 2 * (L_stateBuf + L_delayBuf)) {
1478     return 1;
1479   }
1480 
1481   self->L_stateBufferCplx = 2 * L_stateBuf;
1482   self->delayBufferCplx = self->stateBufferCplx + 2 * L_stateBuf;
1483   self->L_delayBufferCplx = 2 * L_delayBuf;
1484 
1485   return 0;
1486 }
FDKdecorrelateInit(HANDLE_DECORR_DEC hDecorrDec,const INT nrHybBands,const FDK_DECORR_TYPE decorrType,const FDK_DUCKER_TYPE duckerType,const INT decorrConfig,const INT seed,const INT partiallyComplex,const INT useFractDelay,const INT isLegacyPS,const INT initStatesFlag)1487 INT FDKdecorrelateInit(HANDLE_DECORR_DEC hDecorrDec, const INT nrHybBands,
1488                        const FDK_DECORR_TYPE decorrType,
1489                        const FDK_DUCKER_TYPE duckerType, const INT decorrConfig,
1490                        const INT seed, const INT partiallyComplex,
1491                        const INT useFractDelay, const INT isLegacyPS,
1492                        const INT initStatesFlag) {
1493   INT errorCode = 0;
1494   int i, rb, i_start;
1495   int nParamBands = 28;
1496 
1497   INT offsetStateBuffer = 0;
1498   INT offsetDelayBuffer = 0;
1499 
1500   const UCHAR *REV_bandOffset;
1501 
1502   const SCHAR *REV_filterOrder;
1503 
1504   hDecorrDec->partiallyComplex = partiallyComplex;
1505   hDecorrDec->numbins = nrHybBands;
1506 
1507   switch (decorrType) {
1508     case DECORR_PS:
1509       /* ignore decorrConfig, seed */
1510       if (partiallyComplex) {
1511         hDecorrDec->REV_bandOffset = REV_bandOffset_PS_LP;
1512         hDecorrDec->REV_delay = REV_delay_PS_LP;
1513         errorCode = distributeBuffer(hDecorrDec, (168), (533));
1514       } else {
1515         hDecorrDec->REV_bandOffset = REV_bandOffset_PS_HQ;
1516         hDecorrDec->REV_delay = REV_delay_PS_HQ;
1517         errorCode = distributeBuffer(hDecorrDec, (360), (257));
1518       }
1519       hDecorrDec->REV_filterOrder = REV_filterOrder_PS;
1520       hDecorrDec->REV_filtType = REV_filtType_PS;
1521 
1522       /* Initialize ring buffer offsets for PS specific filter implementation.
1523        */
1524       for (i = 0; i < (3); i++)
1525         hDecorrDec->stateBufferOffset[i] = stateBufferOffsetInit[i];
1526 
1527       break;
1528     case DECORR_USAC:
1529       if (partiallyComplex) return 1;
1530       if (seed != 0) return 1;
1531       hDecorrDec->REV_bandOffset =
1532           REV_bandOffset_MPS_HQ[decorrConfig]; /* reverb band layout is
1533                                                   inherited from MPS standard */
1534       hDecorrDec->REV_filterOrder = REV_filterOrder_USAC;
1535       hDecorrDec->REV_delay = REV_delay_USAC;
1536       if (useFractDelay) {
1537         return 1; /* not yet supported */
1538       } else {
1539         hDecorrDec->REV_filtType = REV_filtType_MPS; /* the filter types are
1540                                                         inherited from MPS
1541                                                         standard */
1542       }
1543       /* bsDecorrConfig == 1 is worst case */
1544       errorCode = distributeBuffer(hDecorrDec, (509), (643));
1545       break;
1546     case DECORR_LD:
1547       if (partiallyComplex) return 1;
1548       if (useFractDelay) return 1;
1549       if (decorrConfig > 2) return 1;
1550       if (seed > (MAX_DECORR_SEED_LD - 1)) return 1;
1551       if (!(nrHybBands == 64 || nrHybBands == 32))
1552         return 1; /* actually just qmf bands and no hybrid bands */
1553       hDecorrDec->REV_bandOffset = REV_bandOffset_LD[decorrConfig];
1554       hDecorrDec->REV_filterOrder = REV_filterOrder_MPS; /* the filter orders
1555                                                             are inherited from
1556                                                             MPS standard */
1557       hDecorrDec->REV_delay =
1558           REV_delay_MPS; /* the delays in each reverb band are inherited from
1559                             MPS standard */
1560       hDecorrDec->REV_filtType = REV_filtType_LD;
1561       errorCode = distributeBuffer(hDecorrDec, (825), (373));
1562       break;
1563     default:
1564       return 1;
1565   }
1566 
1567   if (errorCode) {
1568     return errorCode;
1569   }
1570 
1571   if (initStatesFlag) {
1572     FDKmemclear(
1573         hDecorrDec->stateBufferCplx,
1574         hDecorrDec->L_stateBufferCplx * sizeof(*hDecorrDec->stateBufferCplx));
1575     FDKmemclear(
1576         hDecorrDec->delayBufferCplx,
1577         hDecorrDec->L_delayBufferCplx * sizeof(*hDecorrDec->delayBufferCplx));
1578     FDKmemclear(hDecorrDec->reverbBandDelayBufferIndex,
1579                 sizeof(hDecorrDec->reverbBandDelayBufferIndex));
1580   }
1581 
1582   REV_bandOffset = hDecorrDec->REV_bandOffset;
1583 
1584   REV_filterOrder = hDecorrDec->REV_filterOrder;
1585 
1586   i_start = 0;
1587   for (rb = 0; rb < (4); rb++) {
1588     int i_stop;
1589 
1590     i_stop = REV_bandOffset[rb];
1591 
1592     if (i_stop <= i_start) {
1593       continue;
1594     }
1595 
1596     for (i = i_start; i < i_stop; i++) {
1597       switch (decorrType) {
1598         case DECORR_PS:
1599           errorCode = DecorrFilterInitPS(
1600               &hDecorrDec->Filter[i], hDecorrDec->stateBufferCplx,
1601               hDecorrDec->delayBufferCplx, &offsetStateBuffer,
1602               &offsetDelayBuffer, i, rb, hDecorrDec->REV_delay[rb]);
1603           break;
1604         default:
1605           errorCode = DecorrFilterInit(
1606               &hDecorrDec->Filter[i], hDecorrDec->stateBufferCplx,
1607               hDecorrDec->delayBufferCplx, &offsetStateBuffer,
1608               &offsetDelayBuffer, seed, rb, useFractDelay,
1609               hDecorrDec->REV_delay[rb], REV_filterOrder[rb], decorrType);
1610           break;
1611       }
1612     }
1613 
1614     i_start = i_stop;
1615   } /* loop over reverbBands */
1616 
1617   if (!(offsetStateBuffer <= hDecorrDec->L_stateBufferCplx) ||
1618       !(offsetDelayBuffer <= hDecorrDec->L_delayBufferCplx)) {
1619     return errorCode = 1;
1620   }
1621 
1622   if (duckerType == DUCKER_AUTOMATIC) {
1623     /* Choose correct ducker type according to standards: */
1624     switch (decorrType) {
1625       case DECORR_PS:
1626         hDecorrDec->ducker.duckerType = DUCKER_PS;
1627         if (isLegacyPS) {
1628           nParamBands = (20);
1629         } else {
1630           nParamBands = (28);
1631         }
1632         break;
1633       case DECORR_USAC:
1634         hDecorrDec->ducker.duckerType = DUCKER_MPS;
1635         nParamBands = (28);
1636         break;
1637       case DECORR_LD:
1638         hDecorrDec->ducker.duckerType = DUCKER_MPS;
1639         nParamBands = (23);
1640         break;
1641       default:
1642         return 1;
1643     }
1644   }
1645 
1646   errorCode = DuckerInit(
1647       &hDecorrDec->ducker, hDecorrDec->numbins, hDecorrDec->partiallyComplex,
1648       hDecorrDec->ducker.duckerType, nParamBands, initStatesFlag);
1649 
1650   return errorCode;
1651 }
1652 
FDKdecorrelateClose(HANDLE_DECORR_DEC hDecorrDec)1653 INT FDKdecorrelateClose(HANDLE_DECORR_DEC hDecorrDec) {
1654   INT err = 0;
1655 
1656   if (hDecorrDec == NULL) {
1657     return 1;
1658   }
1659 
1660   hDecorrDec->stateBufferCplx = NULL;
1661   hDecorrDec->L_stateBufferCplx = 0;
1662   hDecorrDec->delayBufferCplx = NULL;
1663   hDecorrDec->L_delayBufferCplx = 0;
1664 
1665   return err;
1666 }
1667 
1668 LNK_SECTION_CODE_L1
FDKdecorrelateApply(HANDLE_DECORR_DEC hDecorrDec,FIXP_DBL * dataRealIn,FIXP_DBL * dataImagIn,FIXP_DBL * dataRealOut,FIXP_DBL * dataImagOut,const INT startHybBand)1669 INT FDKdecorrelateApply(HANDLE_DECORR_DEC hDecorrDec, FIXP_DBL *dataRealIn,
1670                         FIXP_DBL *dataImagIn, FIXP_DBL *dataRealOut,
1671                         FIXP_DBL *dataImagOut, const INT startHybBand) {
1672   HANDLE_DECORR_DEC self = hDecorrDec;
1673   INT err = 0;
1674   INT rb, stop, start;
1675 
1676   if (self != NULL) {
1677     int nHybBands = 0;
1678     /* copy new samples */
1679     nHybBands = self->numbins;
1680 
1681     FIXP_DBL directNrg[(28)];
1682 
1683     DuckerCalcEnergy(
1684         &self->ducker, dataRealIn, dataImagIn, directNrg,
1685         self->ducker.maxValDirectData, &(self->ducker.scaleDirectNrg),
1686         (self->ducker.duckerType == DUCKER_PS) ? 1 : 0, startHybBand);
1687 
1688     /* complex-valued hybrid bands */
1689     for (stop = 0, rb = 0; rb < (4); rb++) {
1690       start = fMax(stop, startHybBand);
1691       stop = fMin(self->REV_bandOffset[rb], (UCHAR)nHybBands);
1692 
1693       if (start < stop) {
1694         switch (hDecorrDec->REV_filtType[rb]) {
1695           case DELAY:
1696             err = DecorrFilterApplyPASS(&self->Filter[0], dataRealIn,
1697                                         dataImagIn, dataRealOut, dataImagOut,
1698                                         start, stop, self->REV_delay[rb],
1699                                         self->reverbBandDelayBufferIndex[rb]);
1700             break;
1701           case INDEP_CPLX_PS:
1702             err = DecorrFilterApplyCPLX_PS(
1703                 &self->Filter[0], dataRealIn, dataImagIn, dataRealOut,
1704                 dataImagOut, start, stop, self->REV_filterOrder[rb],
1705                 self->REV_delay[rb], self->reverbBandDelayBufferIndex[rb],
1706                 self->stateBufferOffset);
1707             break;
1708           case COMMON_REAL:
1709             err = DecorrFilterApplyREAL(
1710                 &self->Filter[0], dataRealIn, dataImagIn, dataRealOut,
1711                 dataImagOut, start, stop, self->REV_filterOrder[rb],
1712                 self->REV_delay[rb], self->reverbBandDelayBufferIndex[rb]);
1713             break;
1714           default:
1715             err = 1;
1716             break;
1717         }
1718         if (err != 0) {
1719           goto bail;
1720         }
1721       } /* if start < stop */
1722     }   /* loop over reverb bands */
1723 
1724     for (rb = 0; rb < (4); rb++) {
1725       self->reverbBandDelayBufferIndex[rb] += 2;
1726       if (self->reverbBandDelayBufferIndex[rb] >= 2 * self->REV_delay[rb])
1727         self->reverbBandDelayBufferIndex[rb] = 0;
1728     }
1729 
1730     switch (self->ducker.duckerType) {
1731       case DUCKER_PS:
1732         err = DuckerApplyPS(&self->ducker, directNrg, dataRealOut, dataImagOut,
1733                             startHybBand);
1734         if (err != 0) goto bail;
1735         break;
1736       default:
1737         err = DuckerApply(&self->ducker, directNrg, dataRealOut, dataImagOut,
1738                           startHybBand);
1739         if (err != 0) goto bail;
1740         break;
1741     }
1742   }
1743 
1744 bail:
1745   return err;
1746 }
1747