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