• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2019 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 (2)
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       do {
610         FIXP_DBL delay_re, delay_im, real, imag;
611 
612         real = *dataRealIn++;
613         imag = *dataImagIn++;
614         delay_re = pDelayBuffer[0];
615         delay_im = pDelayBuffer[1];
616         pDelayBuffer[0] = real;
617         pDelayBuffer[1] = imag;
618         *dataRealOut++ = delay_re;
619         *dataImagOut++ = delay_im;
620         pDelayBuffer += offset;
621       } while (--i != 0);
622     }
623   }
624 
625   return (INT)0;
626 }
627 
628 #ifndef FUNCTION_DecorrFilterApplyREAL
629 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)630 static INT DecorrFilterApplyREAL(DECORR_FILTER_INSTANCE const filter[],
631                                  FIXP_DBL *dataRealIn, FIXP_DBL *dataImagIn,
632                                  FIXP_DBL *dataRealOut, FIXP_DBL *dataImagOut,
633                                  INT start, INT stop, INT reverbFilterOrder,
634                                  INT reverbBandNoSampleDelay,
635                                  INT reverbBandDelayBufferIndex) {
636   INT i, j;
637   FIXP_DBL xReal, xImag, yReal, yImag;
638 
639   const FIXP_DECORR *pFilter = filter[start].numeratorReal;
640 
641   INT offsetDelayBuffer = (2 * reverbBandNoSampleDelay) - 1;
642   FIXP_MPS *pDelayBuffer =
643       &filter[start].DelayBufferCplx[reverbBandDelayBufferIndex];
644 
645   INT offsetStates = 2 * reverbFilterOrder;
646   FIXP_DBL *pStates = filter[start].stateCplx;
647 
648   /* Memory for the delayline has been allocated in a consecutive order, so we
649      can address from filter to filter with a constant length. The same is valid
650      for the states.
651      Be aware that real and imaginary part of the delayline and the states are
652      stored in interleaved order.
653      All filter in a reverb band have the same filter coefficients.
654      Exploit symmetry: numeratorReal[i] =
655      denominatorReal[reverbFilterLength-1-i] Do not accumulate the highest
656      states which are always zero.
657   */
658   if (reverbFilterOrder == 2) {
659     FIXP_DECORR nFilt0L, nFilt0H;
660 
661     nFilt0L = pFilter[0];
662     nFilt0H = pFilter[1];
663 
664     for (i = start; i < stop; i++) {
665       xReal = *pDelayBuffer;
666       *pDelayBuffer = dataRealIn[i];
667       pDelayBuffer++;
668 
669       xImag = *pDelayBuffer;
670       *pDelayBuffer = dataImagIn[i];
671       pDelayBuffer += offsetDelayBuffer;
672 
673       yReal = (pStates[0] + fMultDiv2(xReal, nFilt0L)) << FILTER_SF;
674       yImag = (pStates[1] + fMultDiv2(xImag, nFilt0L)) << FILTER_SF;
675 
676       dataRealOut[i] = yReal;
677       dataImagOut[i] = yImag;
678 
679       pStates[0] =
680           pStates[2] + fMultDiv2(xReal, nFilt0H) - fMultDiv2(yReal, nFilt0H);
681       pStates[1] =
682           pStates[3] + fMultDiv2(xImag, nFilt0H) - fMultDiv2(yImag, nFilt0H);
683       pStates[2] = (xReal >> FILTER_SF) - fMultDiv2(yReal, nFilt0L);
684       pStates[3] = (xImag >> FILTER_SF) - fMultDiv2(yImag, nFilt0L);
685       pStates += offsetStates;
686     }
687   } else if (reverbFilterOrder == 3) {
688     FIXP_DECORR nFilt0L, nFilt0H, nFilt1L;
689 
690     nFilt0L = pFilter[0];
691     nFilt0H = pFilter[1];
692     nFilt1L = pFilter[2];
693 
694     for (i = start; i < stop; i++) {
695       xReal = *pDelayBuffer;
696       *pDelayBuffer = dataRealIn[i];
697       pDelayBuffer++;
698 
699       xImag = *pDelayBuffer;
700       *pDelayBuffer = dataImagIn[i];
701       pDelayBuffer += offsetDelayBuffer;
702 
703       yReal = (pStates[0] + fMultDiv2(xReal, nFilt0L)) << FILTER_SF;
704       yImag = (pStates[1] + fMultDiv2(xImag, nFilt0L)) << FILTER_SF;
705 
706       dataRealOut[i] = yReal;
707       dataImagOut[i] = yImag;
708 
709       pStates[0] =
710           pStates[2] + fMultDiv2(xReal, nFilt0H) - fMultDiv2(yReal, nFilt1L);
711       pStates[1] =
712           pStates[3] + fMultDiv2(xImag, nFilt0H) - fMultDiv2(yImag, nFilt1L);
713       pStates[2] =
714           pStates[4] + fMultDiv2(xReal, nFilt1L) - fMultDiv2(yReal, nFilt0H);
715       pStates[3] =
716           pStates[5] + fMultDiv2(xImag, nFilt1L) - fMultDiv2(yImag, nFilt0H);
717       pStates[4] = (xReal >> FILTER_SF) - fMultDiv2(yReal, nFilt0L);
718       pStates[5] = (xImag >> FILTER_SF) - fMultDiv2(yImag, nFilt0L);
719       pStates += offsetStates;
720     }
721   } else if (reverbFilterOrder == 6) {
722     FIXP_DECORR nFilt0L, nFilt0H, nFilt1L, nFilt1H, nFilt2L, nFilt2H;
723 
724     nFilt0L = pFilter[0];
725     nFilt0H = pFilter[1];
726     nFilt1L = pFilter[2];
727     nFilt1H = pFilter[3];
728     nFilt2L = pFilter[4];
729     nFilt2H = pFilter[5];
730 
731     for (i = start; i < stop; i++) {
732       xReal = *pDelayBuffer;
733       *pDelayBuffer = dataRealIn[i];
734       pDelayBuffer++;
735 
736       xImag = *pDelayBuffer;
737       *pDelayBuffer = dataImagIn[i];
738       pDelayBuffer += offsetDelayBuffer;
739 
740       yReal = (pStates[0] + fMultDiv2(xReal, nFilt0L)) << FILTER_SF;
741       yImag = (pStates[1] + fMultDiv2(xImag, nFilt0L)) << FILTER_SF;
742       dataRealOut[i] = yReal;
743       dataImagOut[i] = yImag;
744 
745       pStates[0] =
746           pStates[2] + fMultDiv2(xReal, nFilt0H) - fMultDiv2(yReal, nFilt2H);
747       pStates[1] =
748           pStates[3] + fMultDiv2(xImag, nFilt0H) - fMultDiv2(yImag, nFilt2H);
749       pStates[2] =
750           pStates[4] + fMultDiv2(xReal, nFilt1L) - fMultDiv2(yReal, nFilt2L);
751       pStates[3] =
752           pStates[5] + fMultDiv2(xImag, nFilt1L) - fMultDiv2(yImag, nFilt2L);
753       pStates[4] =
754           pStates[6] + fMultDiv2(xReal, nFilt1H) - fMultDiv2(yReal, nFilt1H);
755       pStates[5] =
756           pStates[7] + fMultDiv2(xImag, nFilt1H) - fMultDiv2(yImag, nFilt1H);
757       pStates[6] =
758           pStates[8] + fMultDiv2(xReal, nFilt2L) - fMultDiv2(yReal, nFilt1L);
759       pStates[7] =
760           pStates[9] + fMultDiv2(xImag, nFilt2L) - fMultDiv2(yImag, nFilt1L);
761       pStates[8] =
762           pStates[10] + fMultDiv2(xReal, nFilt2H) - fMultDiv2(yReal, nFilt0H);
763       pStates[9] =
764           pStates[11] + fMultDiv2(xImag, nFilt2H) - fMultDiv2(yImag, nFilt0H);
765       pStates[10] = (xReal >> FILTER_SF) - fMultDiv2(yReal, nFilt0L);
766       pStates[11] = (xImag >> FILTER_SF) - fMultDiv2(yImag, nFilt0L);
767       pStates += offsetStates;
768     }
769   } else {
770     FIXP_DECORR nFilt0L, nFilt0H;
771     for (i = start; i < stop; i++) {
772       xReal = *pDelayBuffer;
773       *pDelayBuffer = dataRealIn[i];
774       pDelayBuffer++;
775 
776       xImag = *pDelayBuffer;
777       *pDelayBuffer = dataImagIn[i];
778       pDelayBuffer += offsetDelayBuffer;
779 
780       nFilt0L = pFilter[0];
781       yReal = (pStates[0] + fMultDiv2(xReal, nFilt0L)) << 2;
782       yImag = (pStates[1] + fMultDiv2(xImag, nFilt0L)) << 2;
783       dataRealOut[i] = yReal;
784       dataImagOut[i] = yImag;
785 
786       for (j = 1; j < reverbFilterOrder; j++) {
787         nFilt0L = pFilter[j];
788         nFilt0H = pFilter[reverbFilterOrder - j];
789         pStates[2 * j - 2] = pStates[2 * j] + fMultDiv2(xReal, nFilt0L) -
790                              fMultDiv2(yReal, nFilt0H);
791         pStates[2 * j - 1] = pStates[2 * j + 1] + fMultDiv2(xImag, nFilt0L) -
792                              fMultDiv2(yImag, nFilt0H);
793       }
794       nFilt0L = pFilter[j];
795       nFilt0H = pFilter[reverbFilterOrder - j];
796       pStates[2 * j - 2] =
797           fMultDiv2(xReal, nFilt0L) - fMultDiv2(yReal, nFilt0H);
798       pStates[2 * j - 1] =
799           fMultDiv2(xImag, nFilt0L) - fMultDiv2(yImag, nFilt0H);
800 
801       pStates += offsetStates;
802     }
803   }
804 
805   return (INT)0;
806 }
807 #endif /* #ifndef FUNCTION_DecorrFilterApplyREAL */
808 
809 #ifndef FUNCTION_DecorrFilterApplyCPLX_PS
810 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)811 static INT DecorrFilterApplyCPLX_PS(
812     DECORR_FILTER_INSTANCE const filter[], FIXP_DBL *dataRealIn,
813     FIXP_DBL *dataImagIn, FIXP_DBL *dataRealOut, FIXP_DBL *dataImagOut,
814     INT start, INT stop, INT reverbFilterOrder, INT reverbBandNoSampleDelay,
815     INT reverbBandDelayBufferIndex, UCHAR *stateBufferOffset) {
816   /* r = real, j = imaginary */
817   FIXP_DBL r_data_a, j_data_a, r_data_b, j_data_b, r_stage_mult, j_stage_mult;
818   FIXP_STP rj_coeff;
819 
820   /* get pointer to current position in input delay buffer of filter with
821    * starting-index */
822   FIXP_DBL *pDelayBuffer =
823       &filter[start].DelayBufferCplx[reverbBandDelayBufferIndex]; /* increases
824                                                                      by 2 every
825                                                                      other call
826                                                                      of this
827                                                                      function */
828   /* determine the increment for this pointer to get to the correct position in
829    * the delay buffer of the next filter */
830   INT offsetDelayBuffer = (2 * reverbBandNoSampleDelay) - 1;
831 
832   /* pointer to current position in state buffer */
833   FIXP_DBL *pStates = filter[start].stateCplx;
834   INT pStatesIncrement = 2 * reverbFilterOrder;
835 
836   /* stateBufferOffset-pointers */
837   FIXP_DBL *pStateBufferOffset0 = pStates + stateBufferOffset[0];
838   FIXP_DBL *pStateBufferOffset1 = pStates + stateBufferOffset[1];
839   FIXP_DBL *pStateBufferOffset2 = pStates + stateBufferOffset[2];
840 
841   /* traverse all hybrid-bands inbetween start- and stop-index */
842   for (int i = start; i < stop; i++) {
843     /* 1. input delay (real/imaginary values interleaved) */
844 
845     /* load delayed real input value */
846     r_data_a = *pDelayBuffer;
847     /* store incoming real data value to delay buffer and increment pointer */
848     *pDelayBuffer++ = dataRealIn[i];
849 
850     /* load delayed imaginary input value */
851     j_data_a = *pDelayBuffer;
852     /* store incoming imaginary data value to delay buffer */
853     *pDelayBuffer = dataImagIn[i];
854     /* increase delay buffer by offset */
855     pDelayBuffer += offsetDelayBuffer;
856 
857     /* 2. Phi(k)-stage */
858 
859     /* create pointer to coefficient table (real and imaginary coefficients
860      * interleaved) */
861     const FIXP_STP *pCoeffs = filter[i].coeffsPacked;
862 
863     /* the first two entries of the coefficient table are the
864      * Phi(k)-multiplicants */
865     rj_coeff = *pCoeffs++;
866     /* multiply value from input delay buffer by looked-up values */
867     cplxMultDiv2(&r_data_b, &j_data_b, r_data_a, j_data_a, rj_coeff);
868 
869     /* 3. process all three filter stages */
870 
871     /* stage 0 */
872 
873     /* get coefficients from lookup table */
874     rj_coeff = *pCoeffs++;
875 
876     /* multiply output of last stage by coefficient */
877     cplxMultDiv2(&r_stage_mult, &j_stage_mult, r_data_b, j_data_b, rj_coeff);
878     r_stage_mult <<= 1;
879     j_stage_mult <<= 1;
880 
881     /* read and add value from state buffer (this is the input for the next
882      * stage) */
883     r_data_a = r_stage_mult + pStateBufferOffset0[0];
884     j_data_a = j_stage_mult + pStateBufferOffset0[1];
885 
886     /* negate r_data_a to perform multiplication with complex conjugate of
887      * rj_coeff */
888     cplxMultDiv2(&r_stage_mult, &j_stage_mult, -r_data_a, j_data_a, rj_coeff);
889 
890     /* add stage input to shifted result */
891     r_stage_mult = r_data_b + (r_stage_mult << 1);
892     j_stage_mult = j_data_b - (j_stage_mult << 1);
893 
894     /* store result to state buffer */
895     pStateBufferOffset0[0] = r_stage_mult;
896     pStateBufferOffset0[1] = j_stage_mult;
897     pStateBufferOffset0 += pStatesIncrement;
898 
899     /* stage 1 */
900 
901     /* get coefficients from lookup table */
902     rj_coeff = *pCoeffs++;
903 
904     /* multiply output of last stage by coefficient */
905     cplxMultDiv2(&r_stage_mult, &j_stage_mult, r_data_a, j_data_a, rj_coeff);
906     r_stage_mult <<= 1;
907     j_stage_mult <<= 1;
908 
909     /* read and add value from state buffer (this is the input for the next
910      * stage) */
911     r_data_b = r_stage_mult + pStateBufferOffset1[0];
912     j_data_b = j_stage_mult + pStateBufferOffset1[1];
913 
914     /* negate r_data_b to perform multiplication with complex conjugate of
915      * rj_coeff */
916     cplxMultDiv2(&r_stage_mult, &j_stage_mult, -r_data_b, j_data_b, rj_coeff);
917 
918     /* add stage input to shifted result */
919     r_stage_mult = r_data_a + (r_stage_mult << 1);
920     j_stage_mult = j_data_a - (j_stage_mult << 1);
921 
922     /* store result to state buffer */
923     pStateBufferOffset1[0] = r_stage_mult;
924     pStateBufferOffset1[1] = j_stage_mult;
925     pStateBufferOffset1 += pStatesIncrement;
926 
927     /* stage 2 */
928 
929     /* get coefficients from lookup table */
930     rj_coeff = *pCoeffs++;
931 
932     /* multiply output of last stage by coefficient */
933     cplxMultDiv2(&r_stage_mult, &j_stage_mult, r_data_b, j_data_b, rj_coeff);
934     r_stage_mult <<= 1;
935     j_stage_mult <<= 1;
936 
937     /* read and add value from state buffer (this is the input for the next
938      * stage) */
939     r_data_a = r_stage_mult + pStateBufferOffset2[0];
940     j_data_a = j_stage_mult + pStateBufferOffset2[1];
941 
942     /* negate r_data_a to perform multiplication with complex conjugate of
943      * rj_coeff */
944     cplxMultDiv2(&r_stage_mult, &j_stage_mult, -r_data_a, j_data_a, rj_coeff);
945 
946     /* add stage input to shifted result */
947     r_stage_mult = r_data_b + (r_stage_mult << 1);
948     j_stage_mult = j_data_b - (j_stage_mult << 1);
949 
950     /* store result to state buffer */
951     pStateBufferOffset2[0] = r_stage_mult;
952     pStateBufferOffset2[1] = j_stage_mult;
953     pStateBufferOffset2 += pStatesIncrement;
954 
955     /* write filter output */
956     dataRealOut[i] = r_data_a << 1;
957     dataImagOut[i] = j_data_a << 1;
958 
959   } /* end of band/filter loop (outer loop) */
960 
961   /* update stateBufferOffset with respect to ring buffer boundaries */
962   if (stateBufferOffset[0] == 4)
963     stateBufferOffset[0] = 0;
964   else
965     stateBufferOffset[0] += 2;
966 
967   if (stateBufferOffset[1] == 12)
968     stateBufferOffset[1] = 6;
969   else
970     stateBufferOffset[1] += 2;
971 
972   if (stateBufferOffset[2] == 22)
973     stateBufferOffset[2] = 14;
974   else
975     stateBufferOffset[2] += 2;
976 
977   return (INT)0;
978 }
979 
980 #endif /* FUNCTION_DecorrFilterApplyCPLX_PS */
981 
982 /*******************************************************************************
983 *******************************************************************************/
DuckerInit(DUCKER_INSTANCE * const self,int const hybridBands,int partiallyComplex,const FDK_DUCKER_TYPE duckerType,const int nParamBands,int initStatesFlag)984 static INT DuckerInit(DUCKER_INSTANCE *const self, int const hybridBands,
985                       int partiallyComplex, const FDK_DUCKER_TYPE duckerType,
986                       const int nParamBands, int initStatesFlag) {
987   INT errorCode = 0;
988 
989   if (self) {
990     switch (nParamBands) {
991       case (20):
992         FDK_ASSERT(hybridBands == 71);
993         self->mapHybBands2ProcBands = kernels_20_to_71_PS;
994         self->mapProcBands2HybBands = kernels_20_to_71_offset_PS;
995         self->parameterBands = (20);
996         break;
997       case (28):
998 
999         self->mapHybBands2ProcBands = kernels_28_to_71;
1000         self->mapProcBands2HybBands = kernels_28_to_71_offset;
1001         self->parameterBands = (28);
1002         break;
1003       case (23):
1004         FDK_ASSERT(hybridBands == 64 || hybridBands == 32);
1005         self->mapHybBands2ProcBands = kernels_23_to_64;
1006         self->mapProcBands2HybBands = kernels_23_to_64_offset;
1007         self->parameterBands = (23);
1008         break;
1009       default:
1010         return 1;
1011     }
1012     self->qs_next = &self->mapProcBands2HybBands[1];
1013 
1014     self->maxValDirectData = FL2FXCONST_DBL(-1.0f);
1015     self->maxValReverbData = FL2FXCONST_DBL(-1.0f);
1016     self->scaleDirectNrg = 2 * DUCKER_MAX_NRG_SCALE;
1017     self->scaleReverbNrg = 2 * DUCKER_MAX_NRG_SCALE;
1018     self->scaleSmoothDirRevNrg = 2 * DUCKER_MAX_NRG_SCALE;
1019     self->headroomSmoothDirRevNrg = 2 * DUCKER_MAX_NRG_SCALE;
1020     self->hybridBands = hybridBands;
1021     self->partiallyComplex = partiallyComplex;
1022 
1023     if (initStatesFlag && (duckerType == DUCKER_PS)) {
1024       int pb;
1025       for (pb = 0; pb < self->parameterBands; pb++) {
1026         self->SmoothDirRevNrg[pb] = (FIXP_MPS)0;
1027       }
1028     }
1029   } else
1030     errorCode = 1;
1031 
1032   return errorCode;
1033 }
1034 
1035   /*******************************************************************************
1036   *******************************************************************************/
1037 
1038 #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)1039 static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
1040                             FIXP_DBL const inputReal[(71)],
1041                             FIXP_DBL const inputImag[(71)],
1042                             FIXP_DBL energy[(28)], FIXP_DBL inputMaxVal,
1043                             SCHAR *nrgScale, int mode, /* 1:(ps) 0:(else) */
1044                             int startHybBand) {
1045   INT err = 0;
1046   int qs, maxHybBand;
1047   int maxHybridBand = self->hybridBands - 1;
1048 
1049   maxHybBand = maxHybridBand;
1050 
1051   FDKmemclear(energy, (28) * sizeof(FIXP_DBL));
1052 
1053   if (mode == 1) {
1054     int pb;
1055     int clz;
1056     FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
1057 
1058     if (maxVal == FL2FXCONST_DBL(-1.0f)) {
1059       clz = fMin(getScalefactor(&inputReal[startHybBand],
1060                                 fMax(0, maxHybridBand - startHybBand + 1)),
1061                  getScalefactor(&inputImag[startHybBand],
1062                                 fMax(0, maxHybBand - startHybBand + 1)));
1063     } else {
1064       clz = CntLeadingZeros(maxVal) - 1;
1065     }
1066 
1067     clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
1068     *nrgScale = (SCHAR)clz << 1;
1069 
1070     /* Initialize pb since it would stay uninitialized for the case startHybBand
1071      * > maxHybBand. */
1072     pb = SpatialDecGetProcessingBand(maxHybBand, self->mapHybBands2ProcBands);
1073     for (qs = startHybBand; qs <= maxHybBand; qs++) {
1074       pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
1075       energy[pb] = SATURATE_LEFT_SHIFT(
1076           (energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
1077               (fPow2Div2(inputImag[qs] << clz) >> 1),
1078           1, DFRACT_BITS);
1079     }
1080     pb++;
1081 
1082     for (; pb <= SpatialDecGetProcessingBand(maxHybridBand,
1083                                              self->mapHybBands2ProcBands);
1084          pb++) {
1085       FDK_ASSERT(pb != SpatialDecGetProcessingBand(
1086                            qs - 1, self->mapHybBands2ProcBands));
1087       int qs_next;
1088       FIXP_DBL nrg = 0;
1089       qs_next = (int)self->qs_next[pb];
1090       for (; qs < qs_next; qs++) {
1091         nrg = fAddSaturate(nrg, fPow2Div2(inputReal[qs] << clz));
1092       }
1093       energy[pb] = nrg;
1094     }
1095   } else {
1096     int clz;
1097     FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
1098 
1099     maxVal = inputMaxVal;
1100 
1101     if (maxVal == FL2FXCONST_DBL(-1.0f)) {
1102       clz = fMin(getScalefactor(&inputReal[startHybBand],
1103                                 fMax(0, maxHybridBand - startHybBand + 1)),
1104                  getScalefactor(&inputImag[startHybBand],
1105                                 fMax(0, maxHybBand - startHybBand + 1)));
1106     } else {
1107       clz = CntLeadingZeros(maxVal) - 1;
1108     }
1109 
1110     clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
1111     *nrgScale = (SCHAR)clz << 1;
1112 
1113     for (qs = startHybBand; qs <= maxHybBand; qs++) {
1114       int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
1115       energy[pb] = SATURATE_LEFT_SHIFT(
1116           (energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
1117               (fPow2Div2(inputImag[qs] << clz) >> 1),
1118           1, DFRACT_BITS);
1119     }
1120 
1121     for (; qs <= maxHybridBand; qs++) {
1122       int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
1123       energy[pb] = fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz));
1124     }
1125   }
1126 
1127   {
1128     /* Catch overflows which have been observed in erred bitstreams to avoid
1129      * assertion failures later. */
1130     int pb;
1131     for (pb = 0; pb < (28); pb++) {
1132       energy[pb] = (FIXP_DBL)((LONG)energy[pb] & (LONG)MAXVAL_DBL);
1133     }
1134   }
1135   return err;
1136 }
1137 #endif /* #ifndef FUNCTION_DuckerCalcEnergy */
1138 
1139 LNK_SECTION_CODE_L1
DuckerApply(DUCKER_INSTANCE * const self,FIXP_DBL const directNrg[(28)],FIXP_DBL outputReal[(71)],FIXP_DBL outputImag[(71)],int startHybBand)1140 static INT DuckerApply(DUCKER_INSTANCE *const self,
1141                        FIXP_DBL const directNrg[(28)],
1142                        FIXP_DBL outputReal[(71)], FIXP_DBL outputImag[(71)],
1143                        int startHybBand) {
1144   INT err = 0;
1145   int qs = startHybBand;
1146   int qs_next = 0;
1147   int pb = 0;
1148   int startParamBand = 0;
1149   int hybBands;
1150   int hybridBands = self->hybridBands;
1151 
1152   C_ALLOC_SCRATCH_START(reverbNrg, FIXP_DBL, (28));
1153 
1154   FIXP_DBL *smoothDirRevNrg = &self->SmoothDirRevNrg[0];
1155   FIXP_DUCK_GAIN duckGain = 0;
1156 
1157   int doScaleNrg = 0;
1158   int scaleDirectNrg = 0;
1159   int scaleReverbNrg = 0;
1160   int scaleSmoothDirRevNrg = 0;
1161   FIXP_DBL maxDirRevNrg = FL2FXCONST_DBL(0.0);
1162 
1163   hybBands = hybridBands;
1164 
1165   startParamBand =
1166       SpatialDecGetProcessingBand(startHybBand, self->mapHybBands2ProcBands);
1167 
1168   DuckerCalcEnergy(self, outputReal, outputImag, reverbNrg,
1169                    self->maxValReverbData, &(self->scaleReverbNrg), 0,
1170                    startHybBand);
1171 
1172   if ((self->scaleDirectNrg != self->scaleReverbNrg) ||
1173       (self->scaleDirectNrg != self->scaleSmoothDirRevNrg) ||
1174       (self->headroomSmoothDirRevNrg == 0)) {
1175     int scale;
1176 
1177     scale = fixMin(self->scaleDirectNrg, self->scaleSmoothDirRevNrg +
1178                                              self->headroomSmoothDirRevNrg - 1);
1179     scale = fixMin(scale, self->scaleReverbNrg);
1180 
1181     scaleDirectNrg = fMax(fMin(self->scaleDirectNrg - scale, (DFRACT_BITS - 1)),
1182                           -(DFRACT_BITS - 1));
1183     scaleReverbNrg = fMax(fMin(self->scaleReverbNrg - scale, (DFRACT_BITS - 1)),
1184                           -(DFRACT_BITS - 1));
1185     scaleSmoothDirRevNrg =
1186         fMax(fMin(self->scaleSmoothDirRevNrg - scale, (DFRACT_BITS - 1)),
1187              -(DFRACT_BITS - 1));
1188 
1189     self->scaleSmoothDirRevNrg = (SCHAR)scale;
1190 
1191     doScaleNrg = 1;
1192   }
1193   for (pb = startParamBand; pb < self->parameterBands; pb++) {
1194     FIXP_DBL tmp1;
1195     FIXP_DBL tmp2;
1196     INT s;
1197 
1198     /* smoothDirRevNrg[2*pb  ] = fMult(smoothDirRevNrg[2*pb  ],DUCK_ALPHA_FDK) +
1199        fMultDiv2(directNrg[pb],DUCK_ONE_MINUS_ALPHA_X4_FDK);
1200        smoothDirRevNrg[2*pb+1] = fMult(smoothDirRevNrg[2*pb+1],DUCK_ALPHA_FDK) +
1201        fMultDiv2(reverbNrg[pb],DUCK_ONE_MINUS_ALPHA_X4_FDK); tmp1 =
1202        fMult(smoothDirRevNrg[2*pb],DUCK_GAMMA_FDK); tmp2 =
1203        smoothDirRevNrg[2*pb+1] >> 1;
1204     */
1205     tmp1 = smoothDirRevNrg[2 * pb + 0];
1206     tmp2 = smoothDirRevNrg[2 * pb + 1];
1207     tmp1 = fMult(tmp1, DUCK_ALPHA_FDK);
1208     tmp2 = fMult(tmp2, DUCK_ALPHA_FDK);
1209 
1210     if (doScaleNrg) {
1211       int scaleSmoothDirRevNrg_asExponent = -scaleSmoothDirRevNrg;
1212 
1213       tmp1 = scaleValue(tmp1, scaleSmoothDirRevNrg_asExponent);
1214       tmp2 = scaleValue(tmp2, scaleSmoothDirRevNrg_asExponent);
1215       tmp1 = fMultAddDiv2(tmp1, scaleValue(directNrg[pb], -scaleDirectNrg),
1216                           DUCK_ONE_MINUS_ALPHA_X4_FDK);
1217       tmp2 = fMultAddDiv2(tmp2, scaleValue(reverbNrg[pb], -scaleReverbNrg),
1218                           DUCK_ONE_MINUS_ALPHA_X4_FDK);
1219     } else {
1220       tmp1 = fMultAddDiv2(tmp1, directNrg[pb], DUCK_ONE_MINUS_ALPHA_X4_FDK);
1221       tmp2 = fMultAddDiv2(tmp2, reverbNrg[pb], DUCK_ONE_MINUS_ALPHA_X4_FDK);
1222     }
1223 
1224     smoothDirRevNrg[2 * pb] = tmp1;
1225     smoothDirRevNrg[2 * pb + 1] = tmp2;
1226 
1227     maxDirRevNrg |= fAbs(tmp1);
1228     maxDirRevNrg |= fAbs(tmp2);
1229 
1230     tmp1 = fMult(tmp1, DUCK_GAMMA_FDK);
1231     tmp2 = tmp2 >> 1;
1232 
1233     qs_next = fMin((int)self->qs_next[pb], self->hybridBands);
1234 
1235     if (tmp2 > tmp1) { /* true for about 20% */
1236       /* gain smaller than 1.0 */
1237       tmp1 = sqrtFixp(tmp1);
1238       tmp2 = invSqrtNorm2(tmp2, &s);
1239       duckGain = FX_DBL2FX_DUCK_GAIN(fMultDiv2(tmp1, tmp2) << s);
1240     } else { /* true for about 80 % */
1241       tmp2 = smoothDirRevNrg[2 * pb] >> 1;
1242       tmp1 = fMult(smoothDirRevNrg[2 * pb + 1], DUCK_GAMMA_FDK);
1243       if (tmp2 > tmp1) { /* true for about 20% */
1244         if (tmp1 <= (tmp2 >> 2)) {
1245           /* limit gain to 2.0 */
1246           if (qs < hybBands) {
1247             for (; qs < qs_next; qs++) {
1248               outputReal[qs] = outputReal[qs] << 1;
1249               outputImag[qs] = outputImag[qs] << 1;
1250             }
1251           } else {
1252             for (; qs < qs_next; qs++) {
1253               outputReal[qs] = outputReal[qs] << 1;
1254             }
1255           }
1256           /* skip general gain*output section */
1257           continue;
1258         } else {
1259           /* gain from 1.0 to 2.0 */
1260           tmp2 = sqrtFixp(tmp2 >> 2);
1261           tmp1 = invSqrtNorm2(tmp1, &s);
1262           duckGain = FX_DBL2FX_DUCK_GAIN(fMult(tmp1, tmp2) << s);
1263         }
1264       } else { /* true for about 60% */
1265         /* gain = 1.0; output does not change; update qs index */
1266         qs = qs_next;
1267         continue;
1268       }
1269     }
1270 
1271     /* general gain*output section */
1272     if (qs < hybBands) {           /* true for about 39% */
1273       for (; qs < qs_next; qs++) { /* runs about 2 times */
1274         outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
1275         outputImag[qs] = fMultDiv2(outputImag[qs], duckGain) << 2;
1276       }
1277     } else {
1278       for (; qs < qs_next; qs++) {
1279         outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
1280       }
1281     }
1282   } /* pb */
1283 
1284   self->headroomSmoothDirRevNrg =
1285       (SCHAR)fixMax(0, CntLeadingZeros(maxDirRevNrg) - 1);
1286 
1287   C_ALLOC_SCRATCH_END(reverbNrg, FIXP_DBL, (28));
1288 
1289   return err;
1290 }
1291 
1292 LNK_SECTION_CODE_L1
DuckerApplyPS(DUCKER_INSTANCE * const self,FIXP_DBL const directNrg[(28)],FIXP_DBL outputReal[(71)],FIXP_DBL outputImag[(71)],int startHybBand)1293 static INT DuckerApplyPS(DUCKER_INSTANCE *const self,
1294                          FIXP_DBL const directNrg[(28)],
1295                          FIXP_DBL outputReal[(71)], FIXP_DBL outputImag[(71)],
1296                          int startHybBand) {
1297   int qs = startHybBand;
1298   int pb = 0;
1299   int startParamBand =
1300       SpatialDecGetProcessingBand(startHybBand, self->mapHybBands2ProcBands);
1301   int hybBands;
1302 
1303   int doScaleNrg = 0;
1304   int scaleDirectNrg = 0;
1305   int scaleSmoothDirRevNrg = 0;
1306   FIXP_DBL maxDirRevNrg = FL2FXCONST_DBL(0.0);
1307 
1308   if ((self->scaleDirectNrg != self->scaleSmoothDirRevNrg) ||
1309       (self->headroomSmoothDirRevNrg == 0)) {
1310     int scale;
1311 
1312     scale = fixMin(self->scaleDirectNrg, self->scaleSmoothDirRevNrg +
1313                                              self->headroomSmoothDirRevNrg - 2);
1314 
1315     scaleDirectNrg = fMax(fMin(self->scaleDirectNrg - scale, (DFRACT_BITS - 1)),
1316                           -(DFRACT_BITS - 1));
1317     scaleSmoothDirRevNrg =
1318         fMax(fMin(self->scaleSmoothDirRevNrg - scale, (DFRACT_BITS - 1)),
1319              -(DFRACT_BITS - 1));
1320 
1321     self->scaleSmoothDirRevNrg = (SCHAR)scale;
1322 
1323     doScaleNrg = 1;
1324   }
1325 
1326   hybBands = self->hybridBands;
1327 
1328   FDK_ASSERT((self->parameterBands == (28)) || (self->parameterBands == (20)));
1329   for (pb = startParamBand; pb < self->parameterBands; pb++) {
1330     FIXP_DBL directNrg2 = directNrg[pb];
1331 
1332     if (doScaleNrg) {
1333       directNrg2 = scaleValue(directNrg2, -scaleDirectNrg);
1334       self->peakDiff[pb] =
1335           scaleValue(self->peakDiff[pb], -scaleSmoothDirRevNrg);
1336       self->peakDecay[pb] =
1337           scaleValue(self->peakDecay[pb], -scaleSmoothDirRevNrg);
1338       self->SmoothDirRevNrg[pb] =
1339           scaleValue(self->SmoothDirRevNrg[pb], -scaleSmoothDirRevNrg);
1340     }
1341     self->peakDecay[pb] = fixMax(
1342         directNrg2, fMult(self->peakDecay[pb], PS_DUCK_PEAK_DECAY_FACTOR_FDK));
1343     self->peakDiff[pb] =
1344         self->peakDiff[pb] +
1345         fMult(PS_DUCK_FILTER_COEFF_FDK,
1346               (self->peakDecay[pb] - directNrg2 - self->peakDiff[pb]));
1347     self->SmoothDirRevNrg[pb] =
1348         fixMax(self->SmoothDirRevNrg[pb] +
1349                    fMult(PS_DUCK_FILTER_COEFF_FDK,
1350                          (directNrg2 - self->SmoothDirRevNrg[pb])),
1351                FL2FXCONST_DBL(0));
1352 
1353     maxDirRevNrg |= fAbs(self->peakDiff[pb]);
1354     maxDirRevNrg |= fAbs(self->SmoothDirRevNrg[pb]);
1355 
1356     if ((self->peakDiff[pb] == FL2FXCONST_DBL(0)) &&
1357         (self->SmoothDirRevNrg[pb] == FL2FXCONST_DBL(0))) {
1358       int qs_next;
1359 
1360       qs = fMax(qs, SpatialDecGetQmfBand(pb, self->mapProcBands2HybBands));
1361       qs_next = fMin((int)self->qs_next[pb], self->hybridBands);
1362 
1363       FIXP_DBL *pOutputReal = &outputReal[qs];
1364       FIXP_DBL *pOutputImag = &outputImag[qs];
1365 
1366       if (qs < hybBands) {
1367         for (; qs < qs_next; qs++) {
1368           *pOutputReal++ = FL2FXCONST_DBL(0);
1369           *pOutputImag++ = FL2FXCONST_DBL(0);
1370         }
1371       } else {
1372         for (; qs < qs_next; qs++) {
1373           *pOutputReal++ = FL2FXCONST_DBL(0);
1374         }
1375       }
1376     } else if (self->peakDiff[pb] != FL2FXCONST_DBL(0)) {
1377       FIXP_DBL multiplication =
1378           fMult(FL2FXCONST_DUCK(0.75f), self->peakDiff[pb]);
1379       if (multiplication > (self->SmoothDirRevNrg[pb] >> 1)) {
1380         FIXP_DBL num, denom, duckGain;
1381         int scale, qs_next;
1382 
1383         /* implement x/y as (sqrt(x)*invSqrt(y))^2 */
1384         num = sqrtFixp(self->SmoothDirRevNrg[pb] >> 1);
1385         denom = self->peakDiff[pb] +
1386                 FL2FXCONST_DBL(ABS_THR / (32768.0f * 32768.0f * 128.0f * 1.5f));
1387         denom = invSqrtNorm2(denom, &scale);
1388 
1389         /* duck output whether duckGain != 1.f */
1390         qs = fMax(qs, SpatialDecGetQmfBand(pb, self->mapProcBands2HybBands));
1391         qs_next = fMin((int)self->qs_next[pb], self->hybridBands);
1392 
1393         duckGain = fMult(num, denom);
1394         duckGain = fPow2Div2(duckGain << scale);
1395         duckGain = fMultDiv2(FL2FXCONST_DUCK(2.f / 3.f), duckGain) << 3;
1396 
1397         FIXP_DBL *pOutputReal = &outputReal[qs];
1398         FIXP_DBL *pOutputImag = &outputImag[qs];
1399 
1400         if (qs < hybBands) {
1401           for (; qs < qs_next; qs++) {
1402             *pOutputReal = fMult(*pOutputReal, duckGain);
1403             pOutputReal++; /* don't move in front of "=" above, because then the
1404                               fract class treats it differently and provides
1405                               wrong argument to fMult() (seen on win32/msvc8) */
1406             *pOutputImag = fMult(*pOutputImag, duckGain);
1407             pOutputImag++;
1408           }
1409         } else {
1410           for (; qs < qs_next; qs++) {
1411             *pOutputReal = fMult(*pOutputReal, duckGain);
1412             pOutputReal++;
1413           }
1414         }
1415       }
1416     }
1417   } /* pb */
1418 
1419   self->headroomSmoothDirRevNrg =
1420       (SCHAR)fixMax(0, CntLeadingZeros(maxDirRevNrg) - 1);
1421 
1422   return 0;
1423 }
1424 
FDKdecorrelateOpen(HANDLE_DECORR_DEC hDecorrDec,FIXP_DBL * bufferCplx,const INT bufLen)1425 INT FDKdecorrelateOpen(HANDLE_DECORR_DEC hDecorrDec, FIXP_DBL *bufferCplx,
1426                        const INT bufLen) {
1427   HANDLE_DECORR_DEC self = hDecorrDec;
1428 
1429   if (bufLen < (2 * ((825) + (373)))) return 1;
1430 
1431   /* assign all memory to stateBufferCplx. It is reassigned during
1432    * FDKdecorrelateInit() */
1433   self->stateBufferCplx = bufferCplx;
1434   self->L_stateBufferCplx = 0;
1435 
1436   self->delayBufferCplx = NULL;
1437   self->L_delayBufferCplx = 0;
1438 
1439   return 0;
1440 }
1441 
distributeBuffer(HANDLE_DECORR_DEC self,const int L_stateBuf,const int L_delayBuf)1442 static int distributeBuffer(HANDLE_DECORR_DEC self, const int L_stateBuf,
1443                             const int L_delayBuf) {
1444   /* factor 2 because of complex values */
1445   if ((2 * ((825) + (373))) < 2 * (L_stateBuf + L_delayBuf)) {
1446     return 1;
1447   }
1448 
1449   self->L_stateBufferCplx = 2 * L_stateBuf;
1450   self->delayBufferCplx = self->stateBufferCplx + 2 * L_stateBuf;
1451   self->L_delayBufferCplx = 2 * L_delayBuf;
1452 
1453   return 0;
1454 }
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)1455 INT FDKdecorrelateInit(HANDLE_DECORR_DEC hDecorrDec, const INT nrHybBands,
1456                        const FDK_DECORR_TYPE decorrType,
1457                        const FDK_DUCKER_TYPE duckerType, const INT decorrConfig,
1458                        const INT seed, const INT partiallyComplex,
1459                        const INT useFractDelay, const INT isLegacyPS,
1460                        const INT initStatesFlag) {
1461   INT errorCode = 0;
1462   int i, rb, i_start;
1463   int nParamBands = 28;
1464 
1465   INT offsetStateBuffer = 0;
1466   INT offsetDelayBuffer = 0;
1467 
1468   const UCHAR *REV_bandOffset;
1469 
1470   const SCHAR *REV_filterOrder;
1471 
1472   hDecorrDec->partiallyComplex = partiallyComplex;
1473   hDecorrDec->numbins = nrHybBands;
1474 
1475   switch (decorrType) {
1476     case DECORR_PS:
1477       /* ignore decorrConfig, seed */
1478       if (partiallyComplex) {
1479         hDecorrDec->REV_bandOffset = REV_bandOffset_PS_LP;
1480         hDecorrDec->REV_delay = REV_delay_PS_LP;
1481         errorCode = distributeBuffer(hDecorrDec, (168), (533));
1482       } else {
1483         hDecorrDec->REV_bandOffset = REV_bandOffset_PS_HQ;
1484         hDecorrDec->REV_delay = REV_delay_PS_HQ;
1485         errorCode = distributeBuffer(hDecorrDec, (360), (257));
1486       }
1487       hDecorrDec->REV_filterOrder = REV_filterOrder_PS;
1488       hDecorrDec->REV_filtType = REV_filtType_PS;
1489 
1490       /* Initialize ring buffer offsets for PS specific filter implementation.
1491        */
1492       for (i = 0; i < (3); i++)
1493         hDecorrDec->stateBufferOffset[i] = stateBufferOffsetInit[i];
1494 
1495       break;
1496     case DECORR_USAC:
1497       if (partiallyComplex) return 1;
1498       if (seed != 0) return 1;
1499       hDecorrDec->REV_bandOffset =
1500           REV_bandOffset_MPS_HQ[decorrConfig]; /* reverb band layout is
1501                                                   inherited from MPS standard */
1502       hDecorrDec->REV_filterOrder = REV_filterOrder_USAC;
1503       hDecorrDec->REV_delay = REV_delay_USAC;
1504       if (useFractDelay) {
1505         return 1; /* not yet supported */
1506       } else {
1507         hDecorrDec->REV_filtType = REV_filtType_MPS; /* the filter types are
1508                                                         inherited from MPS
1509                                                         standard */
1510       }
1511       /* bsDecorrConfig == 1 is worst case */
1512       errorCode = distributeBuffer(hDecorrDec, (509), (643));
1513       break;
1514     case DECORR_LD:
1515       if (partiallyComplex) return 1;
1516       if (useFractDelay) return 1;
1517       if (decorrConfig > 2) return 1;
1518       if (seed > (MAX_DECORR_SEED_LD - 1)) return 1;
1519       if (!(nrHybBands == 64 || nrHybBands == 32))
1520         return 1; /* actually just qmf bands and no hybrid bands */
1521       hDecorrDec->REV_bandOffset = REV_bandOffset_LD[decorrConfig];
1522       hDecorrDec->REV_filterOrder = REV_filterOrder_MPS; /* the filter orders
1523                                                             are inherited from
1524                                                             MPS standard */
1525       hDecorrDec->REV_delay =
1526           REV_delay_MPS; /* the delays in each reverb band are inherited from
1527                             MPS standard */
1528       hDecorrDec->REV_filtType = REV_filtType_LD;
1529       errorCode = distributeBuffer(hDecorrDec, (825), (373));
1530       break;
1531     default:
1532       return 1;
1533   }
1534 
1535   if (errorCode) {
1536     return errorCode;
1537   }
1538 
1539   if (initStatesFlag) {
1540     FDKmemclear(
1541         hDecorrDec->stateBufferCplx,
1542         hDecorrDec->L_stateBufferCplx * sizeof(*hDecorrDec->stateBufferCplx));
1543     FDKmemclear(
1544         hDecorrDec->delayBufferCplx,
1545         hDecorrDec->L_delayBufferCplx * sizeof(*hDecorrDec->delayBufferCplx));
1546     FDKmemclear(hDecorrDec->reverbBandDelayBufferIndex,
1547                 sizeof(hDecorrDec->reverbBandDelayBufferIndex));
1548   }
1549 
1550   REV_bandOffset = hDecorrDec->REV_bandOffset;
1551 
1552   REV_filterOrder = hDecorrDec->REV_filterOrder;
1553 
1554   i_start = 0;
1555   for (rb = 0; rb < (4); rb++) {
1556     int i_stop;
1557 
1558     i_stop = REV_bandOffset[rb];
1559 
1560     if (i_stop <= i_start) {
1561       continue;
1562     }
1563 
1564     for (i = i_start; i < i_stop; i++) {
1565       switch (decorrType) {
1566         case DECORR_PS:
1567           errorCode = DecorrFilterInitPS(
1568               &hDecorrDec->Filter[i], hDecorrDec->stateBufferCplx,
1569               hDecorrDec->delayBufferCplx, &offsetStateBuffer,
1570               &offsetDelayBuffer, i, rb, hDecorrDec->REV_delay[rb]);
1571           break;
1572         default:
1573           errorCode = DecorrFilterInit(
1574               &hDecorrDec->Filter[i], hDecorrDec->stateBufferCplx,
1575               hDecorrDec->delayBufferCplx, &offsetStateBuffer,
1576               &offsetDelayBuffer, seed, rb, useFractDelay,
1577               hDecorrDec->REV_delay[rb], REV_filterOrder[rb], decorrType);
1578           break;
1579       }
1580     }
1581 
1582     i_start = i_stop;
1583   } /* loop over reverbBands */
1584 
1585   if (!(offsetStateBuffer <= hDecorrDec->L_stateBufferCplx) ||
1586       !(offsetDelayBuffer <= hDecorrDec->L_delayBufferCplx)) {
1587     return errorCode = 1;
1588   }
1589 
1590   if (duckerType == DUCKER_AUTOMATIC) {
1591     /* Choose correct ducker type according to standards: */
1592     switch (decorrType) {
1593       case DECORR_PS:
1594         hDecorrDec->ducker.duckerType = DUCKER_PS;
1595         if (isLegacyPS) {
1596           nParamBands = (20);
1597         } else {
1598           nParamBands = (28);
1599         }
1600         break;
1601       case DECORR_USAC:
1602         hDecorrDec->ducker.duckerType = DUCKER_MPS;
1603         nParamBands = (28);
1604         break;
1605       case DECORR_LD:
1606         hDecorrDec->ducker.duckerType = DUCKER_MPS;
1607         nParamBands = (23);
1608         break;
1609       default:
1610         return 1;
1611     }
1612   }
1613 
1614   errorCode = DuckerInit(
1615       &hDecorrDec->ducker, hDecorrDec->numbins, hDecorrDec->partiallyComplex,
1616       hDecorrDec->ducker.duckerType, nParamBands, initStatesFlag);
1617 
1618   return errorCode;
1619 }
1620 
FDKdecorrelateClose(HANDLE_DECORR_DEC hDecorrDec)1621 INT FDKdecorrelateClose(HANDLE_DECORR_DEC hDecorrDec) {
1622   INT err = 0;
1623 
1624   if (hDecorrDec == NULL) {
1625     return 1;
1626   }
1627 
1628   hDecorrDec->stateBufferCplx = NULL;
1629   hDecorrDec->L_stateBufferCplx = 0;
1630   hDecorrDec->delayBufferCplx = NULL;
1631   hDecorrDec->L_delayBufferCplx = 0;
1632 
1633   return err;
1634 }
1635 
1636 LNK_SECTION_CODE_L1
FDKdecorrelateApply(HANDLE_DECORR_DEC hDecorrDec,FIXP_DBL * dataRealIn,FIXP_DBL * dataImagIn,FIXP_DBL * dataRealOut,FIXP_DBL * dataImagOut,const INT startHybBand)1637 INT FDKdecorrelateApply(HANDLE_DECORR_DEC hDecorrDec, FIXP_DBL *dataRealIn,
1638                         FIXP_DBL *dataImagIn, FIXP_DBL *dataRealOut,
1639                         FIXP_DBL *dataImagOut, const INT startHybBand) {
1640   HANDLE_DECORR_DEC self = hDecorrDec;
1641   INT err = 0;
1642   INT rb, stop, start;
1643 
1644   if (self != NULL) {
1645     int nHybBands = 0;
1646     /* copy new samples */
1647     nHybBands = self->numbins;
1648 
1649     FIXP_DBL directNrg[(28)];
1650 
1651     DuckerCalcEnergy(
1652         &self->ducker, dataRealIn, dataImagIn, directNrg,
1653         self->ducker.maxValDirectData, &(self->ducker.scaleDirectNrg),
1654         (self->ducker.duckerType == DUCKER_PS) ? 1 : 0, startHybBand);
1655 
1656     /* complex-valued hybrid bands */
1657     for (stop = 0, rb = 0; rb < (4); rb++) {
1658       start = fMax(stop, startHybBand);
1659       stop = fMin(self->REV_bandOffset[rb], (UCHAR)nHybBands);
1660 
1661       if (start < stop) {
1662         switch (hDecorrDec->REV_filtType[rb]) {
1663           case DELAY:
1664             err = DecorrFilterApplyPASS(&self->Filter[0], dataRealIn,
1665                                         dataImagIn, dataRealOut, dataImagOut,
1666                                         start, stop, self->REV_delay[rb],
1667                                         self->reverbBandDelayBufferIndex[rb]);
1668             break;
1669           case INDEP_CPLX_PS:
1670             err = DecorrFilterApplyCPLX_PS(
1671                 &self->Filter[0], dataRealIn, dataImagIn, dataRealOut,
1672                 dataImagOut, start, stop, self->REV_filterOrder[rb],
1673                 self->REV_delay[rb], self->reverbBandDelayBufferIndex[rb],
1674                 self->stateBufferOffset);
1675             break;
1676           case COMMON_REAL:
1677             err = DecorrFilterApplyREAL(
1678                 &self->Filter[0], dataRealIn, dataImagIn, dataRealOut,
1679                 dataImagOut, start, stop, self->REV_filterOrder[rb],
1680                 self->REV_delay[rb], self->reverbBandDelayBufferIndex[rb]);
1681             break;
1682           default:
1683             err = 1;
1684             break;
1685         }
1686         if (err != 0) {
1687           goto bail;
1688         }
1689       } /* if start < stop */
1690     }   /* loop over reverb bands */
1691 
1692     for (rb = 0; rb < (4); rb++) {
1693       self->reverbBandDelayBufferIndex[rb] += 2;
1694       if (self->reverbBandDelayBufferIndex[rb] >= 2 * self->REV_delay[rb])
1695         self->reverbBandDelayBufferIndex[rb] = 0;
1696     }
1697 
1698     switch (self->ducker.duckerType) {
1699       case DUCKER_PS:
1700         err = DuckerApplyPS(&self->ducker, directNrg, dataRealOut, dataImagOut,
1701                             startHybBand);
1702         if (err != 0) goto bail;
1703         break;
1704       default:
1705         err = DuckerApply(&self->ducker, directNrg, dataRealOut, dataImagOut,
1706                           startHybBand);
1707         if (err != 0) goto bail;
1708         break;
1709     }
1710   }
1711 
1712 bail:
1713   return err;
1714 }
1715