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