/src/aac/libSBRdec/src/hbe.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* ----------------------------------------------------------------------------- |
2 | | Software License for The Fraunhofer FDK AAC Codec Library for Android |
3 | | |
4 | | © Copyright 1995 - 2021 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 | | /**************************** SBR decoder library ****************************** |
96 | | |
97 | | Author(s): |
98 | | |
99 | | Description: |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | /*! |
104 | | \file |
105 | | \brief Fast FFT routines prototypes |
106 | | \author Fabian Haussel |
107 | | */ |
108 | | |
109 | | #include "hbe.h" |
110 | | #include "qmf.h" |
111 | | #include "env_extr.h" |
112 | | |
113 | | #define HBE_MAX_QMF_BANDS (40) |
114 | | |
115 | 1.86k | #define HBE_MAX_OUT_SLOTS (11) |
116 | | |
117 | | #define QMF_WIN_LEN \ |
118 | 98 | (12 + 6 - 4 - 1) /* 6 subband slots extra delay to align with HQ - 4 slots \ |
119 | | to compensate for critical sampling delay - 1 slot to \ |
120 | | align critical sampling exactly (w additional time \ |
121 | | domain delay)*/ |
122 | | |
123 | | #ifndef PI |
124 | | #define PI 3.14159265358979323846 |
125 | | #endif |
126 | | |
127 | | static const int xProducts[MAX_STRETCH_HBE - 1] = { |
128 | | 1, 1, 1}; /* Cross products on(1)/off(0) for T=2,3,4. */ |
129 | | static const int startSubband2kL[33] = { |
130 | | 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, |
131 | | 6, 8, 8, 8, 8, 8, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12}; |
132 | | |
133 | | static const int pmin = 12; |
134 | | |
135 | | static const FIXP_DBL hintReal_F[4][3] = { |
136 | | {FL2FXCONST_DBL(0.39840335f), FL2FXCONST_DBL(0.39840335f), |
137 | | FL2FXCONST_DBL(-0.39840335f)}, |
138 | | {FL2FXCONST_DBL(0.39840335f), FL2FXCONST_DBL(-0.39840335f), |
139 | | FL2FXCONST_DBL(-0.39840335f)}, |
140 | | {FL2FXCONST_DBL(-0.39840335f), FL2FXCONST_DBL(-0.39840335f), |
141 | | FL2FXCONST_DBL(0.39840335f)}, |
142 | | {FL2FXCONST_DBL(-0.39840335f), FL2FXCONST_DBL(0.39840335f), |
143 | | FL2FXCONST_DBL(0.39840335f)}}; |
144 | | |
145 | | static const FIXP_DBL factors[4] = { |
146 | | FL2FXCONST_DBL(0.39840335f), FL2FXCONST_DBL(-0.39840335f), |
147 | | FL2FXCONST_DBL(-0.39840335f), FL2FXCONST_DBL(0.39840335f)}; |
148 | | |
149 | | #define PSCALE 32 |
150 | | |
151 | | static const FIXP_DBL p_F[128] = {FL2FXCONST_DBL(0.f / (PSCALE * 12.f)), |
152 | | FL2FXCONST_DBL(1.f / (PSCALE * 12.f)), |
153 | | FL2FXCONST_DBL(2.f / (PSCALE * 12.f)), |
154 | | FL2FXCONST_DBL(3.f / (PSCALE * 12.f)), |
155 | | FL2FXCONST_DBL(4.f / (PSCALE * 12.f)), |
156 | | FL2FXCONST_DBL(5.f / (PSCALE * 12.f)), |
157 | | FL2FXCONST_DBL(6.f / (PSCALE * 12.f)), |
158 | | FL2FXCONST_DBL(7.f / (PSCALE * 12.f)), |
159 | | FL2FXCONST_DBL(8.f / (PSCALE * 12.f)), |
160 | | FL2FXCONST_DBL(9.f / (PSCALE * 12.f)), |
161 | | FL2FXCONST_DBL(10.f / (PSCALE * 12.f)), |
162 | | FL2FXCONST_DBL(11.f / (PSCALE * 12.f)), |
163 | | FL2FXCONST_DBL(12.f / (PSCALE * 12.f)), |
164 | | FL2FXCONST_DBL(13.f / (PSCALE * 12.f)), |
165 | | FL2FXCONST_DBL(14.f / (PSCALE * 12.f)), |
166 | | FL2FXCONST_DBL(15.f / (PSCALE * 12.f)), |
167 | | FL2FXCONST_DBL(16.f / (PSCALE * 12.f)), |
168 | | FL2FXCONST_DBL(17.f / (PSCALE * 12.f)), |
169 | | FL2FXCONST_DBL(18.f / (PSCALE * 12.f)), |
170 | | FL2FXCONST_DBL(19.f / (PSCALE * 12.f)), |
171 | | FL2FXCONST_DBL(20.f / (PSCALE * 12.f)), |
172 | | FL2FXCONST_DBL(21.f / (PSCALE * 12.f)), |
173 | | FL2FXCONST_DBL(22.f / (PSCALE * 12.f)), |
174 | | FL2FXCONST_DBL(23.f / (PSCALE * 12.f)), |
175 | | FL2FXCONST_DBL(24.f / (PSCALE * 12.f)), |
176 | | FL2FXCONST_DBL(25.f / (PSCALE * 12.f)), |
177 | | FL2FXCONST_DBL(26.f / (PSCALE * 12.f)), |
178 | | FL2FXCONST_DBL(27.f / (PSCALE * 12.f)), |
179 | | FL2FXCONST_DBL(28.f / (PSCALE * 12.f)), |
180 | | FL2FXCONST_DBL(29.f / (PSCALE * 12.f)), |
181 | | FL2FXCONST_DBL(30.f / (PSCALE * 12.f)), |
182 | | FL2FXCONST_DBL(31.f / (PSCALE * 12.f)), |
183 | | FL2FXCONST_DBL(32.f / (PSCALE * 12.f)), |
184 | | FL2FXCONST_DBL(33.f / (PSCALE * 12.f)), |
185 | | FL2FXCONST_DBL(34.f / (PSCALE * 12.f)), |
186 | | FL2FXCONST_DBL(35.f / (PSCALE * 12.f)), |
187 | | FL2FXCONST_DBL(36.f / (PSCALE * 12.f)), |
188 | | FL2FXCONST_DBL(37.f / (PSCALE * 12.f)), |
189 | | FL2FXCONST_DBL(38.f / (PSCALE * 12.f)), |
190 | | FL2FXCONST_DBL(39.f / (PSCALE * 12.f)), |
191 | | FL2FXCONST_DBL(40.f / (PSCALE * 12.f)), |
192 | | FL2FXCONST_DBL(41.f / (PSCALE * 12.f)), |
193 | | FL2FXCONST_DBL(42.f / (PSCALE * 12.f)), |
194 | | FL2FXCONST_DBL(43.f / (PSCALE * 12.f)), |
195 | | FL2FXCONST_DBL(44.f / (PSCALE * 12.f)), |
196 | | FL2FXCONST_DBL(45.f / (PSCALE * 12.f)), |
197 | | FL2FXCONST_DBL(46.f / (PSCALE * 12.f)), |
198 | | FL2FXCONST_DBL(47.f / (PSCALE * 12.f)), |
199 | | FL2FXCONST_DBL(48.f / (PSCALE * 12.f)), |
200 | | FL2FXCONST_DBL(49.f / (PSCALE * 12.f)), |
201 | | FL2FXCONST_DBL(50.f / (PSCALE * 12.f)), |
202 | | FL2FXCONST_DBL(51.f / (PSCALE * 12.f)), |
203 | | FL2FXCONST_DBL(52.f / (PSCALE * 12.f)), |
204 | | FL2FXCONST_DBL(53.f / (PSCALE * 12.f)), |
205 | | FL2FXCONST_DBL(54.f / (PSCALE * 12.f)), |
206 | | FL2FXCONST_DBL(55.f / (PSCALE * 12.f)), |
207 | | FL2FXCONST_DBL(56.f / (PSCALE * 12.f)), |
208 | | FL2FXCONST_DBL(57.f / (PSCALE * 12.f)), |
209 | | FL2FXCONST_DBL(58.f / (PSCALE * 12.f)), |
210 | | FL2FXCONST_DBL(59.f / (PSCALE * 12.f)), |
211 | | FL2FXCONST_DBL(60.f / (PSCALE * 12.f)), |
212 | | FL2FXCONST_DBL(61.f / (PSCALE * 12.f)), |
213 | | FL2FXCONST_DBL(62.f / (PSCALE * 12.f)), |
214 | | FL2FXCONST_DBL(63.f / (PSCALE * 12.f)), |
215 | | FL2FXCONST_DBL(64.f / (PSCALE * 12.f)), |
216 | | FL2FXCONST_DBL(65.f / (PSCALE * 12.f)), |
217 | | FL2FXCONST_DBL(66.f / (PSCALE * 12.f)), |
218 | | FL2FXCONST_DBL(67.f / (PSCALE * 12.f)), |
219 | | FL2FXCONST_DBL(68.f / (PSCALE * 12.f)), |
220 | | FL2FXCONST_DBL(69.f / (PSCALE * 12.f)), |
221 | | FL2FXCONST_DBL(70.f / (PSCALE * 12.f)), |
222 | | FL2FXCONST_DBL(71.f / (PSCALE * 12.f)), |
223 | | FL2FXCONST_DBL(72.f / (PSCALE * 12.f)), |
224 | | FL2FXCONST_DBL(73.f / (PSCALE * 12.f)), |
225 | | FL2FXCONST_DBL(74.f / (PSCALE * 12.f)), |
226 | | FL2FXCONST_DBL(75.f / (PSCALE * 12.f)), |
227 | | FL2FXCONST_DBL(76.f / (PSCALE * 12.f)), |
228 | | FL2FXCONST_DBL(77.f / (PSCALE * 12.f)), |
229 | | FL2FXCONST_DBL(78.f / (PSCALE * 12.f)), |
230 | | FL2FXCONST_DBL(79.f / (PSCALE * 12.f)), |
231 | | FL2FXCONST_DBL(80.f / (PSCALE * 12.f)), |
232 | | FL2FXCONST_DBL(81.f / (PSCALE * 12.f)), |
233 | | FL2FXCONST_DBL(82.f / (PSCALE * 12.f)), |
234 | | FL2FXCONST_DBL(83.f / (PSCALE * 12.f)), |
235 | | FL2FXCONST_DBL(84.f / (PSCALE * 12.f)), |
236 | | FL2FXCONST_DBL(85.f / (PSCALE * 12.f)), |
237 | | FL2FXCONST_DBL(86.f / (PSCALE * 12.f)), |
238 | | FL2FXCONST_DBL(87.f / (PSCALE * 12.f)), |
239 | | FL2FXCONST_DBL(88.f / (PSCALE * 12.f)), |
240 | | FL2FXCONST_DBL(89.f / (PSCALE * 12.f)), |
241 | | FL2FXCONST_DBL(90.f / (PSCALE * 12.f)), |
242 | | FL2FXCONST_DBL(91.f / (PSCALE * 12.f)), |
243 | | FL2FXCONST_DBL(92.f / (PSCALE * 12.f)), |
244 | | FL2FXCONST_DBL(93.f / (PSCALE * 12.f)), |
245 | | FL2FXCONST_DBL(94.f / (PSCALE * 12.f)), |
246 | | FL2FXCONST_DBL(95.f / (PSCALE * 12.f)), |
247 | | FL2FXCONST_DBL(96.f / (PSCALE * 12.f)), |
248 | | FL2FXCONST_DBL(97.f / (PSCALE * 12.f)), |
249 | | FL2FXCONST_DBL(98.f / (PSCALE * 12.f)), |
250 | | FL2FXCONST_DBL(99.f / (PSCALE * 12.f)), |
251 | | FL2FXCONST_DBL(100.f / (PSCALE * 12.f)), |
252 | | FL2FXCONST_DBL(101.f / (PSCALE * 12.f)), |
253 | | FL2FXCONST_DBL(102.f / (PSCALE * 12.f)), |
254 | | FL2FXCONST_DBL(103.f / (PSCALE * 12.f)), |
255 | | FL2FXCONST_DBL(104.f / (PSCALE * 12.f)), |
256 | | FL2FXCONST_DBL(105.f / (PSCALE * 12.f)), |
257 | | FL2FXCONST_DBL(106.f / (PSCALE * 12.f)), |
258 | | FL2FXCONST_DBL(107.f / (PSCALE * 12.f)), |
259 | | FL2FXCONST_DBL(108.f / (PSCALE * 12.f)), |
260 | | FL2FXCONST_DBL(109.f / (PSCALE * 12.f)), |
261 | | FL2FXCONST_DBL(110.f / (PSCALE * 12.f)), |
262 | | FL2FXCONST_DBL(111.f / (PSCALE * 12.f)), |
263 | | FL2FXCONST_DBL(112.f / (PSCALE * 12.f)), |
264 | | FL2FXCONST_DBL(113.f / (PSCALE * 12.f)), |
265 | | FL2FXCONST_DBL(114.f / (PSCALE * 12.f)), |
266 | | FL2FXCONST_DBL(115.f / (PSCALE * 12.f)), |
267 | | FL2FXCONST_DBL(116.f / (PSCALE * 12.f)), |
268 | | FL2FXCONST_DBL(117.f / (PSCALE * 12.f)), |
269 | | FL2FXCONST_DBL(118.f / (PSCALE * 12.f)), |
270 | | FL2FXCONST_DBL(119.f / (PSCALE * 12.f)), |
271 | | FL2FXCONST_DBL(120.f / (PSCALE * 12.f)), |
272 | | FL2FXCONST_DBL(121.f / (PSCALE * 12.f)), |
273 | | FL2FXCONST_DBL(122.f / (PSCALE * 12.f)), |
274 | | FL2FXCONST_DBL(123.f / (PSCALE * 12.f)), |
275 | | FL2FXCONST_DBL(124.f / (PSCALE * 12.f)), |
276 | | FL2FXCONST_DBL(125.f / (PSCALE * 12.f)), |
277 | | FL2FXCONST_DBL(126.f / (PSCALE * 12.f)), |
278 | | FL2FXCONST_DBL(127.f / (PSCALE * 12.f))}; |
279 | | |
280 | | static const FIXP_DBL band_F[64] = { |
281 | | FL2FXCONST_DBL((0.f * 2.f + 1) / (PSCALE << 2)), |
282 | | FL2FXCONST_DBL((1.f * 2.f + 1) / (PSCALE << 2)), |
283 | | FL2FXCONST_DBL((2.f * 2.f + 1) / (PSCALE << 2)), |
284 | | FL2FXCONST_DBL((3.f * 2.f + 1) / (PSCALE << 2)), |
285 | | FL2FXCONST_DBL((4.f * 2.f + 1) / (PSCALE << 2)), |
286 | | FL2FXCONST_DBL((5.f * 2.f + 1) / (PSCALE << 2)), |
287 | | FL2FXCONST_DBL((6.f * 2.f + 1) / (PSCALE << 2)), |
288 | | FL2FXCONST_DBL((7.f * 2.f + 1) / (PSCALE << 2)), |
289 | | FL2FXCONST_DBL((8.f * 2.f + 1) / (PSCALE << 2)), |
290 | | FL2FXCONST_DBL((9.f * 2.f + 1) / (PSCALE << 2)), |
291 | | FL2FXCONST_DBL((10.f * 2.f + 1) / (PSCALE << 2)), |
292 | | FL2FXCONST_DBL((11.f * 2.f + 1) / (PSCALE << 2)), |
293 | | FL2FXCONST_DBL((12.f * 2.f + 1) / (PSCALE << 2)), |
294 | | FL2FXCONST_DBL((13.f * 2.f + 1) / (PSCALE << 2)), |
295 | | FL2FXCONST_DBL((14.f * 2.f + 1) / (PSCALE << 2)), |
296 | | FL2FXCONST_DBL((15.f * 2.f + 1) / (PSCALE << 2)), |
297 | | FL2FXCONST_DBL((16.f * 2.f + 1) / (PSCALE << 2)), |
298 | | FL2FXCONST_DBL((17.f * 2.f + 1) / (PSCALE << 2)), |
299 | | FL2FXCONST_DBL((18.f * 2.f + 1) / (PSCALE << 2)), |
300 | | FL2FXCONST_DBL((19.f * 2.f + 1) / (PSCALE << 2)), |
301 | | FL2FXCONST_DBL((20.f * 2.f + 1) / (PSCALE << 2)), |
302 | | FL2FXCONST_DBL((21.f * 2.f + 1) / (PSCALE << 2)), |
303 | | FL2FXCONST_DBL((22.f * 2.f + 1) / (PSCALE << 2)), |
304 | | FL2FXCONST_DBL((23.f * 2.f + 1) / (PSCALE << 2)), |
305 | | FL2FXCONST_DBL((24.f * 2.f + 1) / (PSCALE << 2)), |
306 | | FL2FXCONST_DBL((25.f * 2.f + 1) / (PSCALE << 2)), |
307 | | FL2FXCONST_DBL((26.f * 2.f + 1) / (PSCALE << 2)), |
308 | | FL2FXCONST_DBL((27.f * 2.f + 1) / (PSCALE << 2)), |
309 | | FL2FXCONST_DBL((28.f * 2.f + 1) / (PSCALE << 2)), |
310 | | FL2FXCONST_DBL((29.f * 2.f + 1) / (PSCALE << 2)), |
311 | | FL2FXCONST_DBL((30.f * 2.f + 1) / (PSCALE << 2)), |
312 | | FL2FXCONST_DBL((31.f * 2.f + 1) / (PSCALE << 2)), |
313 | | FL2FXCONST_DBL((32.f * 2.f + 1) / (PSCALE << 2)), |
314 | | FL2FXCONST_DBL((33.f * 2.f + 1) / (PSCALE << 2)), |
315 | | FL2FXCONST_DBL((34.f * 2.f + 1) / (PSCALE << 2)), |
316 | | FL2FXCONST_DBL((35.f * 2.f + 1) / (PSCALE << 2)), |
317 | | FL2FXCONST_DBL((36.f * 2.f + 1) / (PSCALE << 2)), |
318 | | FL2FXCONST_DBL((37.f * 2.f + 1) / (PSCALE << 2)), |
319 | | FL2FXCONST_DBL((38.f * 2.f + 1) / (PSCALE << 2)), |
320 | | FL2FXCONST_DBL((39.f * 2.f + 1) / (PSCALE << 2)), |
321 | | FL2FXCONST_DBL((40.f * 2.f + 1) / (PSCALE << 2)), |
322 | | FL2FXCONST_DBL((41.f * 2.f + 1) / (PSCALE << 2)), |
323 | | FL2FXCONST_DBL((42.f * 2.f + 1) / (PSCALE << 2)), |
324 | | FL2FXCONST_DBL((43.f * 2.f + 1) / (PSCALE << 2)), |
325 | | FL2FXCONST_DBL((44.f * 2.f + 1) / (PSCALE << 2)), |
326 | | FL2FXCONST_DBL((45.f * 2.f + 1) / (PSCALE << 2)), |
327 | | FL2FXCONST_DBL((46.f * 2.f + 1) / (PSCALE << 2)), |
328 | | FL2FXCONST_DBL((47.f * 2.f + 1) / (PSCALE << 2)), |
329 | | FL2FXCONST_DBL((48.f * 2.f + 1) / (PSCALE << 2)), |
330 | | FL2FXCONST_DBL((49.f * 2.f + 1) / (PSCALE << 2)), |
331 | | FL2FXCONST_DBL((50.f * 2.f + 1) / (PSCALE << 2)), |
332 | | FL2FXCONST_DBL((51.f * 2.f + 1) / (PSCALE << 2)), |
333 | | FL2FXCONST_DBL((52.f * 2.f + 1) / (PSCALE << 2)), |
334 | | FL2FXCONST_DBL((53.f * 2.f + 1) / (PSCALE << 2)), |
335 | | FL2FXCONST_DBL((54.f * 2.f + 1) / (PSCALE << 2)), |
336 | | FL2FXCONST_DBL((55.f * 2.f + 1) / (PSCALE << 2)), |
337 | | FL2FXCONST_DBL((56.f * 2.f + 1) / (PSCALE << 2)), |
338 | | FL2FXCONST_DBL((57.f * 2.f + 1) / (PSCALE << 2)), |
339 | | FL2FXCONST_DBL((58.f * 2.f + 1) / (PSCALE << 2)), |
340 | | FL2FXCONST_DBL((59.f * 2.f + 1) / (PSCALE << 2)), |
341 | | FL2FXCONST_DBL((60.f * 2.f + 1) / (PSCALE << 2)), |
342 | | FL2FXCONST_DBL((61.f * 2.f + 1) / (PSCALE << 2)), |
343 | | FL2FXCONST_DBL((62.f * 2.f + 1) / (PSCALE << 2)), |
344 | | FL2FXCONST_DBL((63.f * 2.f + 1) / (PSCALE << 2))}; |
345 | | |
346 | | static const FIXP_DBL tr_str[3] = {FL2FXCONST_DBL(1.f / 4.f), |
347 | | FL2FXCONST_DBL(2.f / 4.f), |
348 | | FL2FXCONST_DBL(3.f / 4.f)}; |
349 | | |
350 | | static const FIXP_DBL stretchfac[3] = {FL2FXCONST_DBL(1.f / 2.f), |
351 | | FL2FXCONST_DBL(1.f / 3.f), |
352 | | FL2FXCONST_DBL(1.f / 4.f)}; |
353 | | |
354 | | static const FIXP_DBL cos_F[64] = { |
355 | | 26353028, -79043208, 131685776, -184244944, 236697216, -289006912, |
356 | | 341142496, -393072608, 444773984, -496191392, 547325824, -598114752, |
357 | | 648559104, -698597248, 748230016, -797411904, 846083200, -894275136, |
358 | | 941928192, -989013760, 1035474624, -1081340672, 1126555136, -1171063296, |
359 | | 1214893696, -1257992192, 1300332544, -1341889408, 1382612736, -1422503808, |
360 | | 1461586944, -1499741440, 1537039104, -1573364864, 1608743808, -1643196672, |
361 | | 1676617344, -1709028992, 1740450560, -1770784896, 1800089472, -1828273536, |
362 | | 1855357440, -1881356288, 1906190080, -1929876608, 1952428928, -1973777664, |
363 | | 1993962880, -2012922240, 2030670208, -2047216000, 2062508288, -2076559488, |
364 | | 2089376128, -2100932224, 2111196800, -2120214784, 2127953792, -2134394368, |
365 | | 2139565056, -2143444864, 2146026624, -2147321856}; |
366 | | |
367 | | static const FIXP_DBL twiddle[121] = {1073741824, |
368 | | 1071442860, |
369 | | 1064555814, |
370 | | 1053110176, |
371 | | 1037154959, |
372 | | 1016758484, |
373 | | 992008094, |
374 | | 963009773, |
375 | | 929887697, |
376 | | 892783698, |
377 | | 851856663, |
378 | | 807281846, |
379 | | 759250125, |
380 | | 707967178, |
381 | | 653652607, |
382 | | 596538995, |
383 | | 536870912, |
384 | | 474903865, |
385 | | 410903207, |
386 | | 345142998, |
387 | | 277904834, |
388 | | 209476638, |
389 | | 140151432, |
390 | | 70226075, |
391 | | 0, |
392 | | -70226075, |
393 | | -140151432, |
394 | | -209476638, |
395 | | -277904834, |
396 | | -345142998, |
397 | | -410903207, |
398 | | -474903865, |
399 | | -536870912, |
400 | | -596538995, |
401 | | -653652607, |
402 | | -707967178, |
403 | | -759250125, |
404 | | -807281846, |
405 | | -851856663, |
406 | | -892783698, |
407 | | -929887697, |
408 | | -963009773, |
409 | | -992008094, |
410 | | -1016758484, |
411 | | -1037154959, |
412 | | -1053110176, |
413 | | -1064555814, |
414 | | -1071442860, |
415 | | -1073741824, |
416 | | -1071442860, |
417 | | -1064555814, |
418 | | -1053110176, |
419 | | -1037154959, |
420 | | -1016758484, |
421 | | -992008094, |
422 | | -963009773, |
423 | | -929887697, |
424 | | -892783698, |
425 | | -851856663, |
426 | | -807281846, |
427 | | -759250125, |
428 | | -707967178, |
429 | | -653652607, |
430 | | -596538995, |
431 | | -536870912, |
432 | | -474903865, |
433 | | -410903207, |
434 | | -345142998, |
435 | | -277904834, |
436 | | -209476638, |
437 | | -140151432, |
438 | | -70226075, |
439 | | 0, |
440 | | 70226075, |
441 | | 140151432, |
442 | | 209476638, |
443 | | 277904834, |
444 | | 345142998, |
445 | | 410903207, |
446 | | 474903865, |
447 | | 536870912, |
448 | | 596538995, |
449 | | 653652607, |
450 | | 707967178, |
451 | | 759250125, |
452 | | 807281846, |
453 | | 851856663, |
454 | | 892783698, |
455 | | 929887697, |
456 | | 963009773, |
457 | | 992008094, |
458 | | 1016758484, |
459 | | 1037154959, |
460 | | 1053110176, |
461 | | 1064555814, |
462 | | 1071442860, |
463 | | 1073741824, |
464 | | 1071442860, |
465 | | 1064555814, |
466 | | 1053110176, |
467 | | 1037154959, |
468 | | 1016758484, |
469 | | 992008094, |
470 | | 963009773, |
471 | | 929887697, |
472 | | 892783698, |
473 | | 851856663, |
474 | | 807281846, |
475 | | 759250125, |
476 | | 707967178, |
477 | | 653652607, |
478 | | 596538995, |
479 | | 536870912, |
480 | | 474903865, |
481 | | 410903207, |
482 | | 345142998, |
483 | | 277904834, |
484 | | 209476638, |
485 | | 140151432, |
486 | | 70226075, |
487 | | 0}; |
488 | | |
489 | | #if FIXP_QTW == FIXP_SGL |
490 | | #define HTW(x) (x) |
491 | | #else |
492 | | #define HTW(x) FX_DBL2FX_QTW(FX_SGL2FX_DBL((const FIXP_SGL)x)) |
493 | | #endif |
494 | | |
495 | | static const FIXP_QTW post_twiddle_cos_8[8] = { |
496 | | HTW(-1606), HTW(4756), HTW(-7723), HTW(10394), |
497 | | HTW(-12665), HTW(14449), HTW(-15679), HTW(16305)}; |
498 | | |
499 | | static const FIXP_QTW post_twiddle_cos_16[16] = { |
500 | | HTW(-804), HTW(2404), HTW(-3981), HTW(5520), HTW(-7005), HTW(8423), |
501 | | HTW(-9760), HTW(11003), HTW(-12140), HTW(13160), HTW(-14053), HTW(14811), |
502 | | HTW(-15426), HTW(15893), HTW(-16207), HTW(16364)}; |
503 | | |
504 | | static const FIXP_QTW post_twiddle_cos_24[24] = { |
505 | | HTW(-536), HTW(1606), HTW(-2669), HTW(3720), HTW(-4756), HTW(5771), |
506 | | HTW(-6762), HTW(7723), HTW(-8652), HTW(9543), HTW(-10394), HTW(11200), |
507 | | HTW(-11958), HTW(12665), HTW(-13318), HTW(13913), HTW(-14449), HTW(14924), |
508 | | HTW(-15334), HTW(15679), HTW(-15956), HTW(16165), HTW(-16305), HTW(16375)}; |
509 | | |
510 | | static const FIXP_QTW post_twiddle_cos_32[32] = { |
511 | | HTW(-402), HTW(1205), HTW(-2006), HTW(2801), HTW(-3590), HTW(4370), |
512 | | HTW(-5139), HTW(5897), HTW(-6639), HTW(7366), HTW(-8076), HTW(8765), |
513 | | HTW(-9434), HTW(10080), HTW(-10702), HTW(11297), HTW(-11866), HTW(12406), |
514 | | HTW(-12916), HTW(13395), HTW(-13842), HTW(14256), HTW(-14635), HTW(14978), |
515 | | HTW(-15286), HTW(15557), HTW(-15791), HTW(15986), HTW(-16143), HTW(16261), |
516 | | HTW(-16340), HTW(16379)}; |
517 | | |
518 | | static const FIXP_QTW post_twiddle_cos_40[40] = { |
519 | | HTW(-322), HTW(965), HTW(-1606), HTW(2245), HTW(-2880), HTW(3511), |
520 | | HTW(-4137), HTW(4756), HTW(-5368), HTW(5971), HTW(-6566), HTW(7150), |
521 | | HTW(-7723), HTW(8285), HTW(-8833), HTW(9368), HTW(-9889), HTW(10394), |
522 | | HTW(-10883), HTW(11356), HTW(-11810), HTW(12247), HTW(-12665), HTW(13063), |
523 | | HTW(-13441), HTW(13799), HTW(-14135), HTW(14449), HTW(-14741), HTW(15011), |
524 | | HTW(-15257), HTW(15480), HTW(-15679), HTW(15853), HTW(-16003), HTW(16129), |
525 | | HTW(-16229), HTW(16305), HTW(-16356), HTW(16381)}; |
526 | | |
527 | | static const FIXP_QTW post_twiddle_sin_8[8] = { |
528 | | HTW(16305), HTW(-15679), HTW(14449), HTW(-12665), |
529 | | HTW(10394), HTW(-7723), HTW(4756), HTW(-1606)}; |
530 | | |
531 | | static const FIXP_QTW post_twiddle_sin_16[16] = { |
532 | | HTW(16364), HTW(-16207), HTW(15893), HTW(-15426), HTW(14811), HTW(-14053), |
533 | | HTW(13160), HTW(-12140), HTW(11003), HTW(-9760), HTW(8423), HTW(-7005), |
534 | | HTW(5520), HTW(-3981), HTW(2404), HTW(-804)}; |
535 | | |
536 | | static const FIXP_QTW post_twiddle_sin_24[24] = { |
537 | | HTW(16375), HTW(-16305), HTW(16165), HTW(-15956), HTW(15679), HTW(-15334), |
538 | | HTW(14924), HTW(-14449), HTW(13913), HTW(-13318), HTW(12665), HTW(-11958), |
539 | | HTW(11200), HTW(-10394), HTW(9543), HTW(-8652), HTW(7723), HTW(-6762), |
540 | | HTW(5771), HTW(-4756), HTW(3720), HTW(-2669), HTW(1606), HTW(-536)}; |
541 | | |
542 | | static const FIXP_QTW post_twiddle_sin_32[32] = { |
543 | | HTW(16379), HTW(-16340), HTW(16261), HTW(-16143), HTW(15986), HTW(-15791), |
544 | | HTW(15557), HTW(-15286), HTW(14978), HTW(-14635), HTW(14256), HTW(-13842), |
545 | | HTW(13395), HTW(-12916), HTW(12406), HTW(-11866), HTW(11297), HTW(-10702), |
546 | | HTW(10080), HTW(-9434), HTW(8765), HTW(-8076), HTW(7366), HTW(-6639), |
547 | | HTW(5897), HTW(-5139), HTW(4370), HTW(-3590), HTW(2801), HTW(-2006), |
548 | | HTW(1205), HTW(-402)}; |
549 | | |
550 | | static const FIXP_QTW post_twiddle_sin_40[40] = { |
551 | | HTW(16381), HTW(-16356), HTW(16305), HTW(-16229), HTW(16129), HTW(-16003), |
552 | | HTW(15853), HTW(-15679), HTW(15480), HTW(-15257), HTW(15011), HTW(-14741), |
553 | | HTW(14449), HTW(-14135), HTW(13799), HTW(-13441), HTW(13063), HTW(-12665), |
554 | | HTW(12247), HTW(-11810), HTW(11356), HTW(-10883), HTW(10394), HTW(-9889), |
555 | | HTW(9368), HTW(-8833), HTW(8285), HTW(-7723), HTW(7150), HTW(-6566), |
556 | | HTW(5971), HTW(-5368), HTW(4756), HTW(-4137), HTW(3511), HTW(-2880), |
557 | | HTW(2245), HTW(-1606), HTW(965), HTW(-322)}; |
558 | | |
559 | | static const FIXP_DBL preModCos[32] = { |
560 | | -749875776, 786681536, 711263552, -821592064, -670937792, 854523392, |
561 | | 628995648, -885396032, -585538240, 914135680, 540670208, -940673088, |
562 | | -494499680, 964944384, 447137824, -986891008, -398698816, 1006460096, |
563 | | 349299264, -1023604544, -299058240, 1038283072, 248096752, -1050460288, |
564 | | -196537584, 1060106816, 144504928, -1067199488, -92124160, 1071721152, |
565 | | 39521456, -1073660992}; |
566 | | |
567 | | static const FIXP_DBL preModSin[32] = { |
568 | | 768510144, 730789760, -804379072, -691308864, 838310208, 650162560, |
569 | | -870221760, -607449920, 900036928, 563273856, -927683776, -517740896, |
570 | | 953095808, 470960608, -976211712, -423045728, 996975808, 374111712, |
571 | | -1015338112, -324276416, 1031254400, 273659904, -1044686336, -222384144, |
572 | | 1055601472, 170572640, -1063973632, -118350192, 1069782528, 65842640, |
573 | | -1073014208, -13176464}; |
574 | | |
575 | | /* The cube root function */ |
576 | | /***************************************************************************** |
577 | | |
578 | | functionname: invCubeRootNorm2 |
579 | | description: delivers 1/cuberoot(op) in Q1.31 format and modified exponent |
580 | | |
581 | | *****************************************************************************/ |
582 | 0 | #define CUBE_ROOT_BITS 7 |
583 | | #define CUBE_ROOT_VALUES (128 + 2) |
584 | 0 | #define CUBE_ROOT_BITS_MASK 0x7f |
585 | 0 | #define CUBE_ROOT_FRACT_BITS_MASK 0x007FFFFF |
586 | | /* Inverse cube root table for operands running from 0.5 to 1.0 */ |
587 | | /* (INT) (1.0/cuberoot((op))); */ |
588 | | /* Implicit exponent is 1. */ |
589 | | |
590 | | LNK_SECTION_CONSTDATA |
591 | | static const FIXP_DBL invCubeRootTab[CUBE_ROOT_VALUES] = { |
592 | | (0x50a28be6), (0x506d1172), (0x503823c4), (0x5003c05a), (0x4fcfe4c0), |
593 | | (0x4f9c8e92), (0x4f69bb7d), (0x4f37693b), (0x4f059594), (0x4ed43e5f), |
594 | | (0x4ea36181), (0x4e72fcea), (0x4e430e98), (0x4e139495), (0x4de48cf5), |
595 | | (0x4db5f5db), (0x4d87cd73), (0x4d5a11f2), (0x4d2cc19c), (0x4cffdabb), |
596 | | (0x4cd35ba4), (0x4ca742b7), (0x4c7b8e5c), (0x4c503d05), (0x4c254d2a), |
597 | | (0x4bfabd50), (0x4bd08c00), (0x4ba6b7cd), (0x4b7d3f53), (0x4b542134), |
598 | | (0x4b2b5c18), (0x4b02eeb1), (0x4adad7b8), (0x4ab315ea), (0x4a8ba80d), |
599 | | (0x4a648cec), (0x4a3dc35b), (0x4a174a30), (0x49f1204a), (0x49cb448d), |
600 | | (0x49a5b5e2), (0x49807339), (0x495b7b86), (0x4936cdc2), (0x491268ec), |
601 | | (0x48ee4c08), (0x48ca761f), (0x48a6e63e), (0x48839b76), (0x486094de), |
602 | | (0x483dd190), (0x481b50ad), (0x47f91156), (0x47d712b3), (0x47b553f0), |
603 | | (0x4793d43c), (0x477292c9), (0x47518ece), (0x4730c785), (0x47103c2d), |
604 | | (0x46efec06), (0x46cfd655), (0x46affa61), (0x46905777), (0x4670ece4), |
605 | | (0x4651b9f9), (0x4632be0b), (0x4613f871), (0x45f56885), (0x45d70da5), |
606 | | (0x45b8e72f), (0x459af487), (0x457d3511), (0x455fa835), (0x45424d5d), |
607 | | (0x452523f6), (0x45082b6e), (0x44eb6337), (0x44cecac5), (0x44b2618d), |
608 | | (0x44962708), (0x447a1ab1), (0x445e3c02), (0x44428a7c), (0x4427059e), |
609 | | (0x440bacec), (0x43f07fe9), (0x43d57e1c), (0x43baa70e), (0x439ffa48), |
610 | | (0x43857757), (0x436b1dc8), (0x4350ed2b), (0x4336e511), (0x431d050c), |
611 | | (0x43034cb2), (0x42e9bb98), (0x42d05156), (0x42b70d85), (0x429defc0), |
612 | | (0x4284f7a2), (0x426c24cb), (0x425376d8), (0x423aed6a), (0x42228823), |
613 | | (0x420a46a6), (0x41f22898), (0x41da2d9f), (0x41c25561), (0x41aa9f86), |
614 | | (0x41930bba), (0x417b99a5), (0x416448f5), (0x414d1956), (0x41360a76), |
615 | | (0x411f1c06), (0x41084db5), (0x40f19f35), (0x40db1039), (0x40c4a074), |
616 | | (0x40ae4f9b), (0x40981d64), (0x40820985), (0x406c13b6), (0x40563bb1), |
617 | | (0x4040812e), (0x402ae3e7), (0x40156399), (0x40000000), (0x3FEAB8D9)}; |
618 | | /* n.a. */ |
619 | | static const FIXP_DBL invCubeRootCorrection[3] = {0x40000000, 0x50A28BE6, |
620 | | 0x6597FA95}; |
621 | | |
622 | | /***************************************************************************** |
623 | | * \brief calculate 1.0/cube_root(op), op contains mantissa and exponent |
624 | | * \param op_m: (i) mantissa of operand, must not be zero (0x0000.0000) or |
625 | | * negative |
626 | | * \param op_e: (i) pointer to the exponent of the operand (must be initialized) |
627 | | * and .. (o) pointer to the exponent of the result |
628 | | * \return: (o) mantissa of the result |
629 | | * \description: |
630 | | * This routine calculates the cube root of the input operand, that is |
631 | | * given with its mantissa in Q31 format (FIXP_DBL) and its exponent (INT). |
632 | | * The resulting mantissa is returned in format Q31. The exponent (*op_e) |
633 | | * is modified accordingly. It is not assured, that the result is fully |
634 | | * left-aligned but assumed to have not more than 2 bits headroom. There is one |
635 | | * macro to activate the use of this algorithm: FUNCTION_invCubeRootNorm2 By |
636 | | * means of activating the macro INVCUBEROOTNORM2_LINEAR_INTERPOLATE_HQ, a |
637 | | * slightly higher precision is reachable (by default, not active). For DEBUG |
638 | | * purpose only: a FDK_ASSERT macro validates, if the input mantissa is greater |
639 | | * zero. |
640 | | * |
641 | | */ |
642 | | static |
643 | | #ifdef __arm__ |
644 | | FIXP_DBL __attribute__((always_inline)) |
645 | | invCubeRootNorm2(FIXP_DBL op_m, INT* op_e) |
646 | | #else |
647 | | FIXP_DBL |
648 | | invCubeRootNorm2(FIXP_DBL op_m, INT* op_e) |
649 | | #endif |
650 | 0 | { |
651 | 0 | FDK_ASSERT(op_m > FIXP_DBL(0)); |
652 | | |
653 | | /* normalize input, calculate shift value */ |
654 | 0 | INT exponent = (INT)fNormz(op_m) - 1; |
655 | 0 | op_m <<= exponent; |
656 | |
|
657 | 0 | INT index = (INT)(op_m >> (DFRACT_BITS - 1 - (CUBE_ROOT_BITS + 1))) & |
658 | 0 | CUBE_ROOT_BITS_MASK; |
659 | 0 | FIXP_DBL fract = (FIXP_DBL)(((INT)op_m & CUBE_ROOT_FRACT_BITS_MASK) |
660 | 0 | << (CUBE_ROOT_BITS + 1)); |
661 | 0 | FIXP_DBL diff = invCubeRootTab[index + 1] - invCubeRootTab[index]; |
662 | 0 | op_m = fMultAddDiv2(invCubeRootTab[index], diff << 1, fract); |
663 | | #if defined(INVCUBEROOTNORM2_LINEAR_INTERPOLATE_HQ) |
664 | | /* reg1 = t[i] + (t[i+1]-t[i])*fract ... already computed ... + |
665 | | * (1-fract)fract*(t[i+2]-t[i+1])/2 */ |
666 | | if (fract != (FIXP_DBL)0) { |
667 | | /* fract = fract * (1 - fract) */ |
668 | | fract = fMultDiv2(fract, (FIXP_DBL)((LONG)0x80000000 - (LONG)fract)) << 1; |
669 | | diff = diff - (invCubeRootTab[index + 2] - invCubeRootTab[index + 1]); |
670 | | op_m = fMultAddDiv2(op_m, fract, diff); |
671 | | } |
672 | | #endif /* INVCUBEROOTNORM2_LINEAR_INTERPOLATE_HQ */ |
673 | | |
674 | | /* calculate the output exponent = input * exp/3 = cubicroot(m)*2^(exp/3) |
675 | | * where 2^(exp/3) = 2^k'*2 or 2^k'*2^(1/3) or 2^k'*2^(2/3) */ |
676 | 0 | exponent = exponent - *op_e + 3; |
677 | 0 | INT shift_tmp = |
678 | 0 | ((INT)fMultDiv2((FIXP_SGL)fAbs(exponent), (FIXP_SGL)0x5556)) >> 16; |
679 | 0 | if (exponent < 0) { |
680 | 0 | shift_tmp = -shift_tmp; |
681 | 0 | } |
682 | 0 | INT rem = exponent - 3 * shift_tmp; |
683 | 0 | if (rem < 0) { |
684 | 0 | rem += 3; |
685 | 0 | shift_tmp--; |
686 | 0 | } |
687 | |
|
688 | 0 | *op_e = shift_tmp; |
689 | 0 | op_m = fMultDiv2(op_m, invCubeRootCorrection[rem]) << 2; |
690 | |
|
691 | 0 | return (op_m); |
692 | 0 | } |
693 | | |
694 | | /***************************************************************************** |
695 | | |
696 | | functionname: invFourthRootNorm2 |
697 | | description: delivers 1/FourthRoot(op) in Q1.31 format and modified |
698 | | exponent |
699 | | |
700 | | *****************************************************************************/ |
701 | | |
702 | 0 | #define FOURTHROOT_BITS 7 |
703 | | #define FOURTHROOT_VALUES (128 + 2) |
704 | 0 | #define FOURTHROOT_BITS_MASK 0x7f |
705 | 0 | #define FOURTHROOT_FRACT_BITS_MASK 0x007FFFFF |
706 | | |
707 | | LNK_SECTION_CONSTDATA |
708 | | static const FIXP_DBL invFourthRootTab[FOURTHROOT_VALUES] = { |
709 | | (0x4c1bf829), (0x4bf61977), (0x4bd09843), (0x4bab72ef), (0x4b86a7eb), |
710 | | (0x4b6235ac), (0x4b3e1ab6), (0x4b1a5592), (0x4af6e4d4), (0x4ad3c718), |
711 | | (0x4ab0fb03), (0x4a8e7f42), (0x4a6c5288), (0x4a4a7393), (0x4a28e126), |
712 | | (0x4a079a0c), (0x49e69d16), (0x49c5e91f), (0x49a57d04), (0x498557ac), |
713 | | (0x49657802), (0x4945dcf9), (0x49268588), (0x490770ac), (0x48e89d6a), |
714 | | (0x48ca0ac9), (0x48abb7d6), (0x488da3a6), (0x486fcd4f), (0x485233ed), |
715 | | (0x4834d6a3), (0x4817b496), (0x47faccf0), (0x47de1ee0), (0x47c1a999), |
716 | | (0x47a56c51), (0x47896643), (0x476d96af), (0x4751fcd6), (0x473697ff), |
717 | | (0x471b6773), (0x47006a81), (0x46e5a079), (0x46cb08ae), (0x46b0a279), |
718 | | (0x46966d34), (0x467c683d), (0x466292f4), (0x4648ecbc), (0x462f74fe), |
719 | | (0x46162b20), (0x45fd0e91), (0x45e41ebe), (0x45cb5b19), (0x45b2c315), |
720 | | (0x459a562a), (0x458213cf), (0x4569fb81), (0x45520cbc), (0x453a4701), |
721 | | (0x4522a9d1), (0x450b34b0), (0x44f3e726), (0x44dcc0ba), (0x44c5c0f7), |
722 | | (0x44aee768), (0x4498339e), (0x4481a527), (0x446b3b96), (0x4454f67e), |
723 | | (0x443ed576), (0x4428d815), (0x4412fdf3), (0x43fd46ad), (0x43e7b1de), |
724 | | (0x43d23f23), (0x43bcee1e), (0x43a7be6f), (0x4392afb8), (0x437dc19d), |
725 | | (0x4368f3c5), (0x435445d6), (0x433fb779), (0x432b4856), (0x4316f81a), |
726 | | (0x4302c66f), (0x42eeb305), (0x42dabd8a), (0x42c6e5ad), (0x42b32b21), |
727 | | (0x429f8d96), (0x428c0cc2), (0x4278a859), (0x42656010), (0x4252339e), |
728 | | (0x423f22bc), (0x422c2d23), (0x4219528b), (0x420692b2), (0x41f3ed51), |
729 | | (0x41e16228), (0x41cef0f2), (0x41bc9971), (0x41aa5b62), (0x41983687), |
730 | | (0x41862aa2), (0x41743775), (0x41625cc3), (0x41509a50), (0x413eefe2), |
731 | | (0x412d5d3e), (0x411be22b), (0x410a7e70), (0x40f931d5), (0x40e7fc23), |
732 | | (0x40d6dd24), (0x40c5d4a2), (0x40b4e268), (0x40a40642), (0x40933ffc), |
733 | | (0x40828f64), (0x4071f447), (0x40616e73), (0x4050fdb9), (0x4040a1e6), |
734 | | (0x40305acc), (0x4020283c), (0x40100a08), (0x40000000), (0x3ff009f9), |
735 | | }; |
736 | | |
737 | | static const FIXP_DBL invFourthRootCorrection[4] = {0x40000000, 0x4C1BF829, |
738 | | 0x5A82799A, 0x6BA27E65}; |
739 | | |
740 | | /* The fourth root function */ |
741 | | /***************************************************************************** |
742 | | * \brief calculate 1.0/fourth_root(op), op contains mantissa and exponent |
743 | | * \param op_m: (i) mantissa of operand, must not be zero (0x0000.0000) or |
744 | | * negative |
745 | | * \param op_e: (i) pointer to the exponent of the operand (must be initialized) |
746 | | * and .. (o) pointer to the exponent of the result |
747 | | * \return: (o) mantissa of the result |
748 | | * \description: |
749 | | * This routine calculates the cube root of the input operand, that is |
750 | | * given with its mantissa in Q31 format (FIXP_DBL) and its exponent (INT). |
751 | | * The resulting mantissa is returned in format Q31. The exponent (*op_e) |
752 | | * is modified accordingly. It is not assured, that the result is fully |
753 | | * left-aligned but assumed to have not more than 2 bits headroom. There is one |
754 | | * macro to activate the use of this algorithm: FUNCTION_invFourthRootNorm2 By |
755 | | * means of activating the macro INVFOURTHROOTNORM2_LINEAR_INTERPOLATE_HQ, a |
756 | | * slightly higher precision is reachable (by default, not active). For DEBUG |
757 | | * purpose only: a FDK_ASSERT macro validates, if the input mantissa is greater |
758 | | * zero. |
759 | | * |
760 | | */ |
761 | | |
762 | | /* #define INVFOURTHROOTNORM2_LINEAR_INTERPOLATE_HQ */ |
763 | | |
764 | | static |
765 | | #ifdef __arm__ |
766 | | FIXP_DBL __attribute__((always_inline)) |
767 | | invFourthRootNorm2(FIXP_DBL op_m, INT* op_e) |
768 | | #else |
769 | | FIXP_DBL |
770 | | invFourthRootNorm2(FIXP_DBL op_m, INT* op_e) |
771 | | #endif |
772 | 0 | { |
773 | 0 | FDK_ASSERT(op_m > FL2FXCONST_DBL(0.0)); |
774 | | |
775 | | /* normalize input, calculate shift value */ |
776 | 0 | INT exponent = (INT)fNormz(op_m) - 1; |
777 | 0 | op_m <<= exponent; |
778 | |
|
779 | 0 | INT index = (INT)(op_m >> (DFRACT_BITS - 1 - (FOURTHROOT_BITS + 1))) & |
780 | 0 | FOURTHROOT_BITS_MASK; |
781 | 0 | FIXP_DBL fract = (FIXP_DBL)(((INT)op_m & FOURTHROOT_FRACT_BITS_MASK) |
782 | 0 | << (FOURTHROOT_BITS + 1)); |
783 | 0 | FIXP_DBL diff = invFourthRootTab[index + 1] - invFourthRootTab[index]; |
784 | 0 | op_m = invFourthRootTab[index] + (fMultDiv2(diff, fract) << 1); |
785 | |
|
786 | | #if defined(INVFOURTHROOTNORM2_LINEAR_INTERPOLATE_HQ) |
787 | | /* reg1 = t[i] + (t[i+1]-t[i])*fract ... already computed ... + |
788 | | * (1-fract)fract*(t[i+2]-t[i+1])/2 */ |
789 | | if (fract != (FIXP_DBL)0) { |
790 | | /* fract = fract * (1 - fract) */ |
791 | | fract = fMultDiv2(fract, (FIXP_DBL)((LONG)0x80000000 - (LONG)fract)) << 1; |
792 | | diff = diff - (invFourthRootTab[index + 2] - invFourthRootTab[index + 1]); |
793 | | op_m = fMultAddDiv2(op_m, fract, diff); |
794 | | } |
795 | | #endif /* INVFOURTHROOTNORM2_LINEAR_INTERPOLATE_HQ */ |
796 | |
|
797 | 0 | exponent = exponent - *op_e + 4; |
798 | 0 | INT rem = exponent & 0x00000003; |
799 | 0 | INT shift_tmp = (exponent >> 2); |
800 | |
|
801 | 0 | *op_e = shift_tmp; |
802 | 0 | op_m = fMultDiv2(op_m, invFourthRootCorrection[rem]) << 2; |
803 | |
|
804 | 0 | return (op_m); |
805 | 0 | } |
806 | | |
807 | | /***************************************************************************** |
808 | | |
809 | | functionname: inv3EigthRootNorm2 |
810 | | description: delivers 1/cubert(op) normalized to .5...1 and the shift value |
811 | | of the OUTPUT |
812 | | |
813 | | *****************************************************************************/ |
814 | 0 | #define THREEIGTHROOT_BITS 7 |
815 | | #define THREEIGTHROOT_VALUES (128 + 2) |
816 | 0 | #define THREEIGTHROOT_BITS_MASK 0x7f |
817 | 0 | #define THREEIGTHROOT_FRACT_BITS_MASK 0x007FFFFF |
818 | | |
819 | | LNK_SECTION_CONSTDATA |
820 | | static const FIXP_DBL inv3EigthRootTab[THREEIGTHROOT_VALUES] = { |
821 | | (0x45cae0f2), (0x45b981bf), (0x45a8492a), (0x45973691), (0x45864959), |
822 | | (0x457580e6), (0x4564dca4), (0x45545c00), (0x4543fe6b), (0x4533c35a), |
823 | | (0x4523aa44), (0x4513b2a4), (0x4503dbf7), (0x44f425be), (0x44e48f7b), |
824 | | (0x44d518b6), (0x44c5c0f7), (0x44b687c8), (0x44a76cb8), (0x44986f58), |
825 | | (0x44898f38), (0x447acbef), (0x446c2514), (0x445d9a3f), (0x444f2b0d), |
826 | | (0x4440d71a), (0x44329e07), (0x44247f73), (0x44167b04), (0x4408905e), |
827 | | (0x43fabf28), (0x43ed070b), (0x43df67b0), (0x43d1e0c5), (0x43c471f7), |
828 | | (0x43b71af6), (0x43a9db71), (0x439cb31c), (0x438fa1ab), (0x4382a6d2), |
829 | | (0x4375c248), (0x4368f3c5), (0x435c3b03), (0x434f97bc), (0x434309ac), |
830 | | (0x43369091), (0x432a2c28), (0x431ddc30), (0x4311a06c), (0x4305789c), |
831 | | (0x42f96483), (0x42ed63e5), (0x42e17688), (0x42d59c30), (0x42c9d4a6), |
832 | | (0x42be1fb1), (0x42b27d1a), (0x42a6ecac), (0x429b6e2f), (0x42900172), |
833 | | (0x4284a63f), (0x42795c64), (0x426e23b0), (0x4262fbf2), (0x4257e4f9), |
834 | | (0x424cde96), (0x4241e89a), (0x423702d8), (0x422c2d23), (0x4221674d), |
835 | | (0x4216b12c), (0x420c0a94), (0x4201735b), (0x41f6eb57), (0x41ec725f), |
836 | | (0x41e2084b), (0x41d7acf3), (0x41cd6030), (0x41c321db), (0x41b8f1ce), |
837 | | (0x41aecfe5), (0x41a4bbf8), (0x419ab5e6), (0x4190bd89), (0x4186d2bf), |
838 | | (0x417cf565), (0x41732558), (0x41696277), (0x415faca1), (0x415603b4), |
839 | | (0x414c6792), (0x4142d818), (0x4139552a), (0x412fdea6), (0x41267470), |
840 | | (0x411d1668), (0x4113c472), (0x410a7e70), (0x41014445), (0x40f815d4), |
841 | | (0x40eef302), (0x40e5dbb4), (0x40dccfcd), (0x40d3cf33), (0x40cad9cb), |
842 | | (0x40c1ef7b), (0x40b9102a), (0x40b03bbd), (0x40a7721c), (0x409eb32e), |
843 | | (0x4095feda), (0x408d5508), (0x4084b5a0), (0x407c208b), (0x407395b2), |
844 | | (0x406b14fd), (0x40629e56), (0x405a31a6), (0x4051ced8), (0x404975d5), |
845 | | (0x40412689), (0x4038e0dd), (0x4030a4bd), (0x40287215), (0x402048cf), |
846 | | (0x401828d7), (0x4010121a), (0x40080483), (0x40000000), (0x3ff8047d), |
847 | | }; |
848 | | |
849 | | /* The last value is rounded in order to avoid any overflow due to the values |
850 | | * range of the root table */ |
851 | | static const FIXP_DBL inv3EigthRootCorrection[8] = { |
852 | | 0x40000000, 0x45CAE0F2, 0x4C1BF829, 0x52FF6B55, |
853 | | 0x5A82799A, 0x62B39509, 0x6BA27E65, 0x75606373}; |
854 | | |
855 | | /* The 3/8 root function */ |
856 | | /***************************************************************************** |
857 | | * \brief calculate 1.0/3Eigth_root(op) = 1.0/(x)^(3/8), op contains mantissa |
858 | | * and exponent |
859 | | * \param op_m: (i) mantissa of operand, must not be zero (0x0000.0000) or |
860 | | * negative |
861 | | * \param op_e: (i) pointer to the exponent of the operand (must be initialized) |
862 | | * and .. (o) pointer to the exponent of the result |
863 | | * \return: (o) mantissa of the result |
864 | | * \description: |
865 | | * This routine calculates the cube root of the input operand, that is |
866 | | * given with its mantissa in Q31 format (FIXP_DBL) and its exponent (INT). |
867 | | * The resulting mantissa is returned in format Q31. The exponent (*op_e) |
868 | | * is modified accordingly. It is not assured, that the result is fully |
869 | | * left-aligned but assumed to have not more than 2 bits headroom. There is one |
870 | | * macro to activate the use of this algorithm: FUNCTION_inv3EigthRootNorm2 By |
871 | | * means of activating the macro INVTHREEIGTHROOTNORM2_LINEAR_INTERPOLATE_HQ, a |
872 | | * slightly higher precision is reachable (by default, not active). For DEBUG |
873 | | * purpose only: a FDK_ASSERT macro validates, if the input mantissa is greater |
874 | | * zero. |
875 | | * |
876 | | */ |
877 | | |
878 | | /* #define INVTHREEIGTHROOTNORM2_LINEAR_INTERPOLATE_HQ */ |
879 | | |
880 | | static |
881 | | #ifdef __arm__ |
882 | | FIXP_DBL __attribute__((always_inline)) |
883 | | inv3EigthRootNorm2(FIXP_DBL op_m, INT* op_e) |
884 | | #else |
885 | | FIXP_DBL |
886 | | inv3EigthRootNorm2(FIXP_DBL op_m, INT* op_e) |
887 | | #endif |
888 | 0 | { |
889 | 0 | FDK_ASSERT(op_m > FL2FXCONST_DBL(0.0)); |
890 | | |
891 | | /* normalize input, calculate shift op_mue */ |
892 | 0 | INT exponent = (INT)fNormz(op_m) - 1; |
893 | 0 | op_m <<= exponent; |
894 | |
|
895 | 0 | INT index = (INT)(op_m >> (DFRACT_BITS - 1 - (THREEIGTHROOT_BITS + 1))) & |
896 | 0 | THREEIGTHROOT_BITS_MASK; |
897 | 0 | FIXP_DBL fract = (FIXP_DBL)(((INT)op_m & THREEIGTHROOT_FRACT_BITS_MASK) |
898 | 0 | << (THREEIGTHROOT_BITS + 1)); |
899 | 0 | FIXP_DBL diff = inv3EigthRootTab[index + 1] - inv3EigthRootTab[index]; |
900 | 0 | op_m = inv3EigthRootTab[index] + (fMultDiv2(diff, fract) << 1); |
901 | |
|
902 | | #if defined(INVTHREEIGTHROOTNORM2_LINEAR_INTERPOLATE_HQ) |
903 | | /* op_m = t[i] + (t[i+1]-t[i])*fract ... already computed ... + |
904 | | * (1-fract)fract*(t[i+2]-t[i+1])/2 */ |
905 | | if (fract != (FIXP_DBL)0) { |
906 | | /* fract = fract * (1 - fract) */ |
907 | | fract = fMultDiv2(fract, (FIXP_DBL)((LONG)0x80000000 - (LONG)fract)) << 1; |
908 | | diff = diff - (inv3EigthRootTab[index + 2] - inv3EigthRootTab[index + 1]); |
909 | | op_m = fMultAddDiv2(op_m, fract, diff); |
910 | | } |
911 | | #endif /* INVTHREEIGTHROOTNORM2_LINEAR_INTERPOLATE_HQ */ |
912 | |
|
913 | 0 | exponent = exponent - *op_e + 8; |
914 | 0 | INT rem = exponent & 0x00000007; |
915 | 0 | INT shift_tmp = (exponent >> 3); |
916 | |
|
917 | 0 | *op_e = shift_tmp * 3; |
918 | 0 | op_m = fMultDiv2(op_m, inv3EigthRootCorrection[rem]) << 2; |
919 | |
|
920 | 0 | return (fMult(op_m, fMult(op_m, op_m))); |
921 | 0 | } |
922 | | |
923 | | SBR_ERROR |
924 | | QmfTransposerCreate(HANDLE_HBE_TRANSPOSER* hQmfTransposer, const int frameSize, |
925 | 49 | int bDisableCrossProducts, int bSbr41) { |
926 | 49 | HANDLE_HBE_TRANSPOSER hQmfTran = NULL; |
927 | | |
928 | 49 | int i; |
929 | | |
930 | 49 | if (hQmfTransposer != NULL) { |
931 | | /* Memory allocation */ |
932 | | /*--------------------------------------------------------------------------------------------*/ |
933 | 49 | hQmfTran = |
934 | 49 | (HANDLE_HBE_TRANSPOSER)FDKcalloc(1, sizeof(struct hbeTransposer)); |
935 | 49 | if (hQmfTran == NULL) { |
936 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
937 | 0 | } |
938 | | |
939 | 196 | for (i = 0; i < MAX_STRETCH_HBE - 1; i++) { |
940 | 147 | hQmfTran->bXProducts[i] = (bDisableCrossProducts ? 0 : xProducts[i]); |
941 | 147 | } |
942 | | |
943 | 49 | hQmfTran->timeDomainWinLen = frameSize; |
944 | 49 | if (frameSize == 768) { |
945 | 19 | hQmfTran->noCols = |
946 | 19 | (8 * frameSize / 3) / QMF_SYNTH_CHANNELS; /* 32 for 24:64 */ |
947 | 30 | } else { |
948 | 30 | hQmfTran->noCols = |
949 | 30 | (bSbr41 + 1) * 2 * frameSize / |
950 | 30 | QMF_SYNTH_CHANNELS; /* 32 for 32:64 and 64 for 16:64 -> identical to |
951 | | sbrdec->no_cols */ |
952 | 30 | } |
953 | | |
954 | 49 | hQmfTran->noChannels = frameSize / hQmfTran->noCols; |
955 | | |
956 | 49 | hQmfTran->qmfInBufSize = QMF_WIN_LEN; |
957 | 49 | hQmfTran->qmfOutBufSize = 2 * (hQmfTran->noCols / 2 + QMF_WIN_LEN - 1); |
958 | | |
959 | 49 | hQmfTran->inBuf_F = |
960 | 49 | (LONG*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(LONG)); |
961 | | /* buffered time signal needs to be delayed by synthesis_size; max |
962 | | * synthesis_size = 20; */ |
963 | 49 | if (hQmfTran->inBuf_F == NULL) { |
964 | 0 | QmfTransposerClose(hQmfTran); |
965 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
966 | 0 | } |
967 | | |
968 | 49 | hQmfTran->qmfInBufReal_F = |
969 | 49 | (FIXP_DBL**)FDKcalloc(hQmfTran->qmfInBufSize, sizeof(FIXP_DBL*)); |
970 | 49 | hQmfTran->qmfInBufImag_F = |
971 | 49 | (FIXP_DBL**)FDKcalloc(hQmfTran->qmfInBufSize, sizeof(FIXP_DBL*)); |
972 | | |
973 | 49 | if (hQmfTran->qmfInBufReal_F == NULL) { |
974 | 0 | QmfTransposerClose(hQmfTran); |
975 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
976 | 0 | } |
977 | 49 | if (hQmfTran->qmfInBufImag_F == NULL) { |
978 | 0 | QmfTransposerClose(hQmfTran); |
979 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
980 | 0 | } |
981 | | |
982 | 686 | for (i = 0; i < hQmfTran->qmfInBufSize; i++) { |
983 | 637 | hQmfTran->qmfInBufReal_F[i] = (FIXP_DBL*)FDKaalloc( |
984 | 637 | QMF_SYNTH_CHANNELS * sizeof(FIXP_DBL), ALIGNMENT_DEFAULT); |
985 | 637 | hQmfTran->qmfInBufImag_F[i] = (FIXP_DBL*)FDKaalloc( |
986 | 637 | QMF_SYNTH_CHANNELS * sizeof(FIXP_DBL), ALIGNMENT_DEFAULT); |
987 | 637 | if (hQmfTran->qmfInBufReal_F[i] == NULL) { |
988 | 0 | QmfTransposerClose(hQmfTran); |
989 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
990 | 0 | } |
991 | 637 | if (hQmfTran->qmfInBufImag_F[i] == NULL) { |
992 | 0 | QmfTransposerClose(hQmfTran); |
993 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
994 | 0 | } |
995 | 637 | } |
996 | | |
997 | 49 | hQmfTran->qmfHBEBufReal_F = |
998 | 49 | (FIXP_DBL**)FDKcalloc(HBE_MAX_OUT_SLOTS, sizeof(FIXP_DBL*)); |
999 | 49 | hQmfTran->qmfHBEBufImag_F = |
1000 | 49 | (FIXP_DBL**)FDKcalloc(HBE_MAX_OUT_SLOTS, sizeof(FIXP_DBL*)); |
1001 | | |
1002 | 49 | if (hQmfTran->qmfHBEBufReal_F == NULL) { |
1003 | 0 | QmfTransposerClose(hQmfTran); |
1004 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
1005 | 0 | } |
1006 | 49 | if (hQmfTran->qmfHBEBufImag_F == NULL) { |
1007 | 0 | QmfTransposerClose(hQmfTran); |
1008 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
1009 | 0 | } |
1010 | | |
1011 | 588 | for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) { |
1012 | 539 | hQmfTran->qmfHBEBufReal_F[i] = |
1013 | 539 | (FIXP_DBL*)FDKcalloc(QMF_SYNTH_CHANNELS, sizeof(FIXP_DBL)); |
1014 | 539 | hQmfTran->qmfHBEBufImag_F[i] = |
1015 | 539 | (FIXP_DBL*)FDKcalloc(QMF_SYNTH_CHANNELS, sizeof(FIXP_DBL)); |
1016 | 539 | if (hQmfTran->qmfHBEBufReal_F[i] == NULL) { |
1017 | 0 | QmfTransposerClose(hQmfTran); |
1018 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
1019 | 0 | } |
1020 | 539 | if (hQmfTran->qmfHBEBufImag_F[i] == NULL) { |
1021 | 0 | QmfTransposerClose(hQmfTran); |
1022 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
1023 | 0 | } |
1024 | 539 | } |
1025 | | |
1026 | 49 | hQmfTran->qmfBufferCodecTempSlot_F = |
1027 | 49 | (FIXP_DBL*)FDKcalloc(QMF_SYNTH_CHANNELS / 2, sizeof(FIXP_DBL)); |
1028 | 49 | if (hQmfTran->qmfBufferCodecTempSlot_F == NULL) { |
1029 | 0 | QmfTransposerClose(hQmfTran); |
1030 | 0 | return SBRDEC_MEM_ALLOC_FAILED; |
1031 | 0 | } |
1032 | | |
1033 | 49 | hQmfTran->bSbr41 = bSbr41; |
1034 | | |
1035 | 49 | hQmfTran->highband_exp[0] = 0; |
1036 | 49 | hQmfTran->highband_exp[1] = 0; |
1037 | 49 | hQmfTran->target_exp[0] = 0; |
1038 | 49 | hQmfTran->target_exp[1] = 0; |
1039 | | |
1040 | 49 | *hQmfTransposer = hQmfTran; |
1041 | 49 | } |
1042 | | |
1043 | 49 | return SBRDEC_OK; |
1044 | 49 | } |
1045 | | |
1046 | | SBR_ERROR QmfTransposerReInit(HANDLE_HBE_TRANSPOSER hQmfTransposer, |
1047 | | UCHAR* FreqBandTable[2], UCHAR NSfb[2]) |
1048 | | /* removed bSbr41 from parameterlist: |
1049 | | don't know where to get this value from |
1050 | | at call-side */ |
1051 | 0 | { |
1052 | 0 | int L, sfb, patch, stopPatch, qmfErr; |
1053 | |
|
1054 | 0 | if (hQmfTransposer != NULL) { |
1055 | 0 | const FIXP_QTW* tmp_t_cos; |
1056 | 0 | const FIXP_QTW* tmp_t_sin; |
1057 | |
|
1058 | 0 | hQmfTransposer->startBand = FreqBandTable[0][0]; |
1059 | 0 | FDK_ASSERT((!hQmfTransposer->bSbr41 && hQmfTransposer->startBand <= 32) || |
1060 | 0 | (hQmfTransposer->bSbr41 && |
1061 | 0 | hQmfTransposer->startBand <= |
1062 | 0 | 16)); /* is checked by resetFreqBandTables() */ |
1063 | 0 | hQmfTransposer->stopBand = FreqBandTable[0][NSfb[0]]; |
1064 | |
|
1065 | 0 | hQmfTransposer->synthSize = |
1066 | 0 | 4 * ((hQmfTransposer->startBand + 4) / 8 + 1); /* 8, 12, 16, 20 */ |
1067 | 0 | hQmfTransposer->kstart = startSubband2kL[hQmfTransposer->startBand]; |
1068 | | |
1069 | | /* don't know where to take this information from */ |
1070 | | /* hQmfTransposer->bSbr41 = bSbr41; */ |
1071 | |
|
1072 | 0 | if (hQmfTransposer->bSbr41) { |
1073 | 0 | if (hQmfTransposer->kstart + hQmfTransposer->synthSize > 16) |
1074 | 0 | hQmfTransposer->kstart = 16 - hQmfTransposer->synthSize; |
1075 | 0 | } else if (hQmfTransposer->timeDomainWinLen == 768) { |
1076 | 0 | if (hQmfTransposer->kstart + hQmfTransposer->synthSize > 24) |
1077 | 0 | hQmfTransposer->kstart = 24 - hQmfTransposer->synthSize; |
1078 | 0 | } |
1079 | |
|
1080 | 0 | hQmfTransposer->synthesisQmfPreModCos_F = |
1081 | 0 | &preModCos[hQmfTransposer->kstart]; |
1082 | 0 | hQmfTransposer->synthesisQmfPreModSin_F = |
1083 | 0 | &preModSin[hQmfTransposer->kstart]; |
1084 | |
|
1085 | 0 | L = 2 * hQmfTransposer->synthSize; /* 8, 16, 24, 32, 40 */ |
1086 | | /* Change analysis post twiddles */ |
1087 | |
|
1088 | 0 | switch (L) { |
1089 | 0 | case 8: |
1090 | 0 | tmp_t_cos = post_twiddle_cos_8; |
1091 | 0 | tmp_t_sin = post_twiddle_sin_8; |
1092 | 0 | break; |
1093 | 0 | case 16: |
1094 | 0 | tmp_t_cos = post_twiddle_cos_16; |
1095 | 0 | tmp_t_sin = post_twiddle_sin_16; |
1096 | 0 | break; |
1097 | 0 | case 24: |
1098 | 0 | tmp_t_cos = post_twiddle_cos_24; |
1099 | 0 | tmp_t_sin = post_twiddle_sin_24; |
1100 | 0 | break; |
1101 | 0 | case 32: |
1102 | 0 | tmp_t_cos = post_twiddle_cos_32; |
1103 | 0 | tmp_t_sin = post_twiddle_sin_32; |
1104 | 0 | break; |
1105 | 0 | case 40: |
1106 | 0 | tmp_t_cos = post_twiddle_cos_40; |
1107 | 0 | tmp_t_sin = post_twiddle_sin_40; |
1108 | 0 | break; |
1109 | 0 | default: |
1110 | 0 | return SBRDEC_UNSUPPORTED_CONFIG; |
1111 | 0 | } |
1112 | | |
1113 | 0 | qmfErr = qmfInitSynthesisFilterBank( |
1114 | 0 | &hQmfTransposer->HBESynthesisQMF, hQmfTransposer->synQmfStates, |
1115 | 0 | hQmfTransposer->noCols, 0, hQmfTransposer->synthSize, |
1116 | 0 | hQmfTransposer->synthSize, 1); |
1117 | 0 | if (qmfErr != 0) { |
1118 | 0 | return SBRDEC_UNSUPPORTED_CONFIG; |
1119 | 0 | } |
1120 | | |
1121 | 0 | qmfErr = qmfInitAnalysisFilterBank( |
1122 | 0 | &hQmfTransposer->HBEAnalysiscQMF, hQmfTransposer->anaQmfStates, |
1123 | 0 | hQmfTransposer->noCols / 2, 0, 2 * hQmfTransposer->synthSize, |
1124 | 0 | 2 * hQmfTransposer->synthSize, 0); |
1125 | |
|
1126 | 0 | if (qmfErr != 0) { |
1127 | 0 | return SBRDEC_UNSUPPORTED_CONFIG; |
1128 | 0 | } |
1129 | | |
1130 | 0 | hQmfTransposer->HBEAnalysiscQMF.t_cos = tmp_t_cos; |
1131 | 0 | hQmfTransposer->HBEAnalysiscQMF.t_sin = tmp_t_sin; |
1132 | |
|
1133 | 0 | FDKmemset(hQmfTransposer->xOverQmf, 0, |
1134 | 0 | MAX_NUM_PATCHES * sizeof(int)); /* global */ |
1135 | 0 | sfb = 0; |
1136 | 0 | if (hQmfTransposer->bSbr41) { |
1137 | 0 | stopPatch = MAX_NUM_PATCHES; |
1138 | 0 | hQmfTransposer->maxStretch = MAX_STRETCH_HBE; |
1139 | 0 | } else { |
1140 | 0 | stopPatch = MAX_STRETCH_HBE; |
1141 | 0 | } |
1142 | |
|
1143 | 0 | for (patch = 1; patch <= stopPatch; patch++) { |
1144 | 0 | while (sfb <= NSfb[0] && |
1145 | 0 | FreqBandTable[0][sfb] <= patch * hQmfTransposer->startBand) |
1146 | 0 | sfb++; |
1147 | 0 | if (sfb <= NSfb[0]) { |
1148 | | /* If the distance is larger than three QMF bands - try aligning to high |
1149 | | * resolution frequency bands instead. */ |
1150 | 0 | if ((patch * hQmfTransposer->startBand - FreqBandTable[0][sfb - 1]) <= |
1151 | 0 | 3) { |
1152 | 0 | hQmfTransposer->xOverQmf[patch - 1] = FreqBandTable[0][sfb - 1]; |
1153 | 0 | } else { |
1154 | 0 | int sfb_tmp = 0; |
1155 | 0 | while (sfb_tmp <= NSfb[1] && |
1156 | 0 | FreqBandTable[1][sfb_tmp] <= patch * hQmfTransposer->startBand) |
1157 | 0 | sfb_tmp++; |
1158 | 0 | hQmfTransposer->xOverQmf[patch - 1] = FreqBandTable[1][sfb_tmp - 1]; |
1159 | 0 | } |
1160 | 0 | } else { |
1161 | 0 | hQmfTransposer->xOverQmf[patch - 1] = hQmfTransposer->stopBand; |
1162 | 0 | hQmfTransposer->maxStretch = fMin(patch, MAX_STRETCH_HBE); |
1163 | 0 | break; |
1164 | 0 | } |
1165 | 0 | } |
1166 | |
|
1167 | 0 | hQmfTransposer->highband_exp[0] = 0; |
1168 | 0 | hQmfTransposer->highband_exp[1] = 0; |
1169 | 0 | hQmfTransposer->target_exp[0] = 0; |
1170 | 0 | hQmfTransposer->target_exp[1] = 0; |
1171 | 0 | } |
1172 | | |
1173 | 0 | return SBRDEC_OK; |
1174 | 0 | } |
1175 | | |
1176 | 49 | void QmfTransposerClose(HANDLE_HBE_TRANSPOSER hQmfTransposer) { |
1177 | 49 | int i; |
1178 | | |
1179 | 49 | if (hQmfTransposer != NULL) { |
1180 | 49 | if (hQmfTransposer->inBuf_F) FDKfree(hQmfTransposer->inBuf_F); |
1181 | | |
1182 | 49 | if (hQmfTransposer->qmfInBufReal_F) { |
1183 | 686 | for (i = 0; i < hQmfTransposer->qmfInBufSize; i++) { |
1184 | 637 | FDKafree(hQmfTransposer->qmfInBufReal_F[i]); |
1185 | 637 | } |
1186 | 49 | FDKfree(hQmfTransposer->qmfInBufReal_F); |
1187 | 49 | } |
1188 | | |
1189 | 49 | if (hQmfTransposer->qmfInBufImag_F) { |
1190 | 686 | for (i = 0; i < hQmfTransposer->qmfInBufSize; i++) { |
1191 | 637 | FDKafree(hQmfTransposer->qmfInBufImag_F[i]); |
1192 | 637 | } |
1193 | 49 | FDKfree(hQmfTransposer->qmfInBufImag_F); |
1194 | 49 | } |
1195 | | |
1196 | 49 | if (hQmfTransposer->qmfHBEBufReal_F) { |
1197 | 588 | for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) { |
1198 | 539 | FDKfree(hQmfTransposer->qmfHBEBufReal_F[i]); |
1199 | 539 | } |
1200 | 49 | FDKfree(hQmfTransposer->qmfHBEBufReal_F); |
1201 | 49 | } |
1202 | | |
1203 | 49 | if (hQmfTransposer->qmfHBEBufImag_F) { |
1204 | 588 | for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) { |
1205 | 539 | FDKfree(hQmfTransposer->qmfHBEBufImag_F[i]); |
1206 | 539 | } |
1207 | 49 | FDKfree(hQmfTransposer->qmfHBEBufImag_F); |
1208 | 49 | } |
1209 | | |
1210 | 49 | FDKfree(hQmfTransposer->qmfBufferCodecTempSlot_F); |
1211 | | |
1212 | 49 | FDKfree(hQmfTransposer); |
1213 | 49 | } |
1214 | 49 | } |
1215 | | |
1216 | 0 | inline void scaleUp(FIXP_DBL* real_m, FIXP_DBL* imag_m, INT* _e) { |
1217 | 0 | INT reserve; |
1218 | | /* shift gc_r and gc_i up if possible */ |
1219 | 0 | reserve = CntLeadingZeros((INT(*real_m) ^ INT((*real_m >> 31))) | |
1220 | 0 | (INT(*imag_m) ^ INT((*imag_m >> 31)))) - |
1221 | 0 | 1; |
1222 | 0 | reserve = fMax(reserve - 1, |
1223 | 0 | 0); /* Leave one bit headroom such that (real_m^2 + imag_m^2) |
1224 | | does not overflow later if both are 0x80000000. */ |
1225 | 0 | reserve = fMin(reserve, *_e); |
1226 | 0 | FDK_ASSERT(reserve >= 0); |
1227 | 0 | *real_m <<= reserve; |
1228 | 0 | *imag_m <<= reserve; |
1229 | 0 | *_e -= reserve; |
1230 | 0 | } |
1231 | | |
1232 | | static void calculateCenterFIXP(FIXP_DBL gammaVecReal, FIXP_DBL gammaVecImag, |
1233 | | FIXP_DBL* centerReal, FIXP_DBL* centerImag, |
1234 | 0 | INT* exponent, int stretch, int mult) { |
1235 | 0 | scaleUp(&gammaVecReal, &gammaVecImag, exponent); |
1236 | 0 | FIXP_DBL energy = fPow2Div2(gammaVecReal) + fPow2Div2(gammaVecImag); |
1237 | |
|
1238 | 0 | if (energy != FL2FXCONST_DBL(0.f)) { |
1239 | 0 | FIXP_DBL gc_r_m, gc_i_m, factor_m = (FIXP_DBL)0; |
1240 | 0 | INT factor_e, gc_e; |
1241 | 0 | factor_e = 2 * (*exponent) + 1; |
1242 | |
|
1243 | 0 | switch (stretch) { |
1244 | 0 | case 2: |
1245 | 0 | factor_m = invFourthRootNorm2(energy, &factor_e); |
1246 | 0 | break; |
1247 | 0 | case 3: |
1248 | 0 | factor_m = invCubeRootNorm2(energy, &factor_e); |
1249 | 0 | break; |
1250 | 0 | case 4: |
1251 | 0 | factor_m = inv3EigthRootNorm2(energy, &factor_e); |
1252 | 0 | break; |
1253 | 0 | } |
1254 | | |
1255 | 0 | gc_r_m = fMultDiv2(gammaVecReal, |
1256 | 0 | factor_m); /* exponent = HBE_SCALE + factor_e + 1 */ |
1257 | 0 | gc_i_m = fMultDiv2(gammaVecImag, |
1258 | 0 | factor_m); /* exponent = HBE_SCALE + factor_e + 1*/ |
1259 | 0 | gc_e = *exponent + factor_e + 1; |
1260 | |
|
1261 | 0 | scaleUp(&gc_r_m, &gc_i_m, &gc_e); |
1262 | |
|
1263 | 0 | switch (mult) { |
1264 | 0 | case 0: |
1265 | 0 | *centerReal = gc_r_m; |
1266 | 0 | *centerImag = gc_i_m; |
1267 | 0 | break; |
1268 | 0 | case 1: |
1269 | 0 | *centerReal = fPow2Div2(gc_r_m) - fPow2Div2(gc_i_m); |
1270 | 0 | *centerImag = fMult(gc_r_m, gc_i_m); |
1271 | 0 | gc_e = 2 * gc_e + 1; |
1272 | 0 | break; |
1273 | 0 | case 2: |
1274 | 0 | FIXP_DBL tmp_r = gc_r_m; |
1275 | 0 | FIXP_DBL tmp_i = gc_i_m; |
1276 | 0 | gc_r_m = fPow2Div2(gc_r_m) - fPow2Div2(gc_i_m); |
1277 | 0 | gc_i_m = fMult(tmp_r, gc_i_m); |
1278 | 0 | gc_e = 3 * gc_e + 1 + 1; |
1279 | 0 | cplxMultDiv2(¢erReal[0], ¢erImag[0], gc_r_m, gc_i_m, tmp_r, |
1280 | 0 | tmp_i); |
1281 | 0 | break; |
1282 | 0 | } |
1283 | | |
1284 | 0 | scaleUp(centerReal, centerImag, &gc_e); |
1285 | |
|
1286 | 0 | FDK_ASSERT(gc_e >= 0); |
1287 | 0 | *exponent = gc_e; |
1288 | 0 | } else { |
1289 | 0 | *centerReal = energy; /* energy = 0 */ |
1290 | 0 | *centerImag = energy; /* energy = 0 */ |
1291 | 0 | *exponent = (INT)energy; |
1292 | 0 | } |
1293 | 0 | } |
1294 | | |
1295 | | static int getHBEScaleFactorFrame(const int bSbr41, const int maxStretch, |
1296 | 0 | const int pitchInBins) { |
1297 | 0 | if (pitchInBins >= pmin * (1 + bSbr41)) { |
1298 | | /* crossproducts enabled */ |
1299 | 0 | return 26; |
1300 | 0 | } else { |
1301 | 0 | return (maxStretch == 2) ? 24 : 25; |
1302 | 0 | } |
1303 | 0 | } |
1304 | | |
1305 | | static void addHighBandPart(FIXP_DBL g_r_m, FIXP_DBL g_i_m, INT g_e, |
1306 | | FIXP_DBL mult, FIXP_DBL gammaCenterReal_m, |
1307 | | FIXP_DBL gammaCenterImag_m, INT gammaCenter_e, |
1308 | | INT stretch, INT scale_factor_hbe, |
1309 | | FIXP_DBL* qmfHBEBufReal_F, |
1310 | 0 | FIXP_DBL* qmfHBEBufImag_F) { |
1311 | 0 | if ((g_r_m | g_i_m) != FL2FXCONST_DBL(0.f)) { |
1312 | 0 | FIXP_DBL factor_m = (FIXP_DBL)0; |
1313 | 0 | INT factor_e; |
1314 | 0 | INT add = (stretch == 4) ? 1 : 0; |
1315 | 0 | INT shift = (stretch == 4) ? 1 : 2; |
1316 | |
|
1317 | 0 | scaleUp(&g_r_m, &g_i_m, &g_e); |
1318 | 0 | FIXP_DBL energy = fPow2AddDiv2(fPow2Div2(g_r_m), g_i_m); |
1319 | 0 | factor_e = 2 * g_e + 1; |
1320 | |
|
1321 | 0 | switch (stretch) { |
1322 | 0 | case 2: |
1323 | 0 | factor_m = invFourthRootNorm2(energy, &factor_e); |
1324 | 0 | break; |
1325 | 0 | case 3: |
1326 | 0 | factor_m = invCubeRootNorm2(energy, &factor_e); |
1327 | 0 | break; |
1328 | 0 | case 4: |
1329 | 0 | factor_m = inv3EigthRootNorm2(energy, &factor_e); |
1330 | 0 | break; |
1331 | 0 | } |
1332 | | |
1333 | 0 | factor_m = fMult(factor_m, mult); |
1334 | |
|
1335 | 0 | FIXP_DBL tmp_r, tmp_i; |
1336 | 0 | cplxMultDiv2(&tmp_r, &tmp_i, g_r_m, g_i_m, gammaCenterReal_m, |
1337 | 0 | gammaCenterImag_m); |
1338 | |
|
1339 | 0 | g_r_m = fMultDiv2(tmp_r, factor_m) << shift; |
1340 | 0 | g_i_m = fMultDiv2(tmp_i, factor_m) << shift; |
1341 | 0 | g_e = scale_factor_hbe - (g_e + factor_e + gammaCenter_e + add); |
1342 | 0 | g_e = fMax((INT)0, g_e); |
1343 | 0 | *qmfHBEBufReal_F += g_r_m >> g_e; |
1344 | 0 | *qmfHBEBufImag_F += g_i_m >> g_e; |
1345 | 0 | } |
1346 | 0 | } |
1347 | | |
1348 | | void QmfTransposerApply(HANDLE_HBE_TRANSPOSER hQmfTransposer, |
1349 | | FIXP_DBL** qmfBufferCodecReal, |
1350 | | FIXP_DBL** qmfBufferCodecImag, int nColsIn, |
1351 | | FIXP_DBL** ppQmfBufferOutReal_F, |
1352 | | FIXP_DBL** ppQmfBufferOutImag_F, |
1353 | | FIXP_DBL lpcFilterStatesReal[2 + (3 * (4))][(64)], |
1354 | | FIXP_DBL lpcFilterStatesImag[2 + (3 * (4))][(64)], |
1355 | | int pitchInBins, int scale_lb, int scale_hbe, |
1356 | | int* scale_hb, int timeStep, int firstSlotOffsset, |
1357 | | int ov_len, |
1358 | 0 | KEEP_STATES_SYNCED_MODE keepStatesSyncedMode) { |
1359 | 0 | int i, j, stretch, band, sourceband, r, s; |
1360 | 0 | int qmfVocoderColsIn = hQmfTransposer->noCols / 2; |
1361 | 0 | int bSbr41 = hQmfTransposer->bSbr41; |
1362 | |
|
1363 | 0 | const int winLength[3] = {10, 8, 6}; |
1364 | 0 | const int slotOffset = 6; /* hQmfTransposer->winLen-6; */ |
1365 | |
|
1366 | 0 | int qmfOffset = 2 * hQmfTransposer->kstart; |
1367 | 0 | int scale_border = (nColsIn == 64) ? 32 : nColsIn; |
1368 | |
|
1369 | 0 | INT slot_stretch4[9] = {0, 0, 0, 0, 2, 4, 6, 8, 10}; |
1370 | 0 | INT slot_stretch2[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; |
1371 | 0 | INT slot_stretch3[10] = {0, 0, 0, 1, 3, 4, 6, 7, 9, 10}; |
1372 | 0 | INT filt_stretch3[10] = {0, 0, 0, 1, 0, 1, 0, 1, 0, 1}; |
1373 | 0 | INT filt_dummy[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
1374 | 0 | INT* pSlotStretch; |
1375 | 0 | INT* pFilt; |
1376 | |
|
1377 | 0 | int offset = 0; /* where to take QmfTransposer data */ |
1378 | |
|
1379 | 0 | int signPreMod = |
1380 | 0 | (hQmfTransposer->synthesisQmfPreModCos_F[0] < FL2FXCONST_DBL(0.f)) ? 1 |
1381 | 0 | : -1; |
1382 | |
|
1383 | 0 | int scale_factor_hbe = |
1384 | 0 | getHBEScaleFactorFrame(bSbr41, hQmfTransposer->maxStretch, pitchInBins); |
1385 | |
|
1386 | 0 | if (keepStatesSyncedMode != KEEP_STATES_SYNCED_OFF) { |
1387 | 0 | offset = hQmfTransposer->noCols - ov_len - LPC_ORDER; |
1388 | 0 | } |
1389 | |
|
1390 | 0 | hQmfTransposer->highband_exp[0] = hQmfTransposer->highband_exp[1]; |
1391 | 0 | hQmfTransposer->target_exp[0] = hQmfTransposer->target_exp[1]; |
1392 | |
|
1393 | 0 | hQmfTransposer->highband_exp[1] = scale_factor_hbe; |
1394 | 0 | hQmfTransposer->target_exp[1] = |
1395 | 0 | fixMax(hQmfTransposer->highband_exp[1], hQmfTransposer->highband_exp[0]); |
1396 | |
|
1397 | 0 | scale_factor_hbe = hQmfTransposer->target_exp[1]; |
1398 | |
|
1399 | 0 | int shift_ov = hQmfTransposer->target_exp[0] - hQmfTransposer->target_exp[1]; |
1400 | |
|
1401 | 0 | if (shift_ov != 0) { |
1402 | 0 | for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) { |
1403 | 0 | scaleValuesSaturate(&hQmfTransposer->qmfHBEBufReal_F[i][0], |
1404 | 0 | QMF_SYNTH_CHANNELS, shift_ov); |
1405 | 0 | scaleValuesSaturate(&hQmfTransposer->qmfHBEBufImag_F[i][0], |
1406 | 0 | QMF_SYNTH_CHANNELS, shift_ov); |
1407 | 0 | } |
1408 | |
|
1409 | 0 | if (keepStatesSyncedMode == KEEP_STATES_SYNCED_OFF) { |
1410 | 0 | int nBands = |
1411 | 0 | fMax(0, hQmfTransposer->stopBand - hQmfTransposer->startBand); |
1412 | |
|
1413 | 0 | for (i = timeStep * firstSlotOffsset; i < ov_len; i++) { |
1414 | 0 | scaleValuesSaturate(&ppQmfBufferOutReal_F[i][hQmfTransposer->startBand], |
1415 | 0 | nBands, shift_ov); |
1416 | 0 | scaleValuesSaturate(&ppQmfBufferOutImag_F[i][hQmfTransposer->startBand], |
1417 | 0 | nBands, shift_ov); |
1418 | 0 | } |
1419 | | |
1420 | | /* shift lpc filterstates */ |
1421 | 0 | for (i = 0; i < timeStep * firstSlotOffsset + LPC_ORDER; i++) { |
1422 | 0 | scaleValuesSaturate(&lpcFilterStatesReal[i][0], (64), shift_ov); |
1423 | 0 | scaleValuesSaturate(&lpcFilterStatesImag[i][0], (64), shift_ov); |
1424 | 0 | } |
1425 | 0 | } |
1426 | 0 | } |
1427 | |
|
1428 | 0 | FIXP_DBL twid_m_new[3][2]; /* [stretch][cos/sin] */ |
1429 | 0 | INT stepsize = 1 + !bSbr41, sine_offset = 24, mod = 96; |
1430 | 0 | INT mult[3] = {1, 2, 3}; |
1431 | |
|
1432 | 0 | for (s = 0; s <= MAX_STRETCH_HBE - 2; s++) { |
1433 | 0 | twid_m_new[s][0] = twiddle[(mult[s] * (stepsize * pitchInBins)) % mod]; |
1434 | 0 | twid_m_new[s][1] = |
1435 | 0 | twiddle[((mult[s] * (stepsize * pitchInBins)) + sine_offset) % mod]; |
1436 | 0 | } |
1437 | | |
1438 | | /* Time-stretch */ |
1439 | 0 | for (j = 0; j < qmfVocoderColsIn; j++) { |
1440 | 0 | int sign = -1, k, z, addrshift, codecTemp_e; |
1441 | | /* update inbuf */ |
1442 | 0 | for (i = 0; i < hQmfTransposer->synthSize; i++) { |
1443 | 0 | hQmfTransposer->inBuf_F[i] = |
1444 | 0 | hQmfTransposer->inBuf_F[i + 2 * hQmfTransposer->synthSize]; |
1445 | 0 | } |
1446 | | |
1447 | | /* run synthesis for two sbr slots as transposer uses |
1448 | | half slots double bands representation */ |
1449 | 0 | for (z = 0; z < 2; z++) { |
1450 | 0 | int scale_factor = ((nColsIn == 64) && ((2 * j + z) < scale_border)) |
1451 | 0 | ? scale_lb |
1452 | 0 | : scale_hbe; |
1453 | 0 | codecTemp_e = scale_factor - 1; /* -2 for Div2 and cos/sin scale of 1 */ |
1454 | |
|
1455 | 0 | for (k = 0; k < hQmfTransposer->synthSize; k++) { |
1456 | 0 | int ki = hQmfTransposer->kstart + k; |
1457 | 0 | hQmfTransposer->qmfBufferCodecTempSlot_F[k] = |
1458 | 0 | fMultDiv2(signPreMod * hQmfTransposer->synthesisQmfPreModCos_F[k], |
1459 | 0 | qmfBufferCodecReal[2 * j + z][ki]); |
1460 | 0 | hQmfTransposer->qmfBufferCodecTempSlot_F[k] += |
1461 | 0 | fMultDiv2(signPreMod * hQmfTransposer->synthesisQmfPreModSin_F[k], |
1462 | 0 | qmfBufferCodecImag[2 * j + z][ki]); |
1463 | 0 | } |
1464 | |
|
1465 | 0 | C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, (HBE_MAX_QMF_BANDS << 1)); |
1466 | |
|
1467 | 0 | qmfSynthesisFilteringSlot( |
1468 | 0 | &hQmfTransposer->HBESynthesisQMF, |
1469 | 0 | hQmfTransposer->qmfBufferCodecTempSlot_F, NULL, 0, |
1470 | 0 | -7 - hQmfTransposer->HBESynthesisQMF.filterScale - codecTemp_e + 1, |
1471 | 0 | hQmfTransposer->inBuf_F + hQmfTransposer->synthSize * (z + 1), 1, |
1472 | 0 | pWorkBuffer); |
1473 | |
|
1474 | 0 | C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, (HBE_MAX_QMF_BANDS << 1)); |
1475 | 0 | } |
1476 | |
|
1477 | 0 | C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, (HBE_MAX_QMF_BANDS << 1)); |
1478 | |
|
1479 | 0 | qmfAnalysisFilteringSlot(&hQmfTransposer->HBEAnalysiscQMF, |
1480 | 0 | hQmfTransposer->qmfInBufReal_F[QMF_WIN_LEN - 1], |
1481 | 0 | hQmfTransposer->qmfInBufImag_F[QMF_WIN_LEN - 1], |
1482 | 0 | hQmfTransposer->inBuf_F + 1, 1, pWorkBuffer); |
1483 | |
|
1484 | 0 | C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, (HBE_MAX_QMF_BANDS << 1)); |
1485 | |
|
1486 | 0 | if ((keepStatesSyncedMode == KEEP_STATES_SYNCED_NORMAL) && |
1487 | 0 | j <= qmfVocoderColsIn - ((LPC_ORDER + ov_len + QMF_WIN_LEN - 1) >> 1)) { |
1488 | | /* update in buffer */ |
1489 | 0 | for (i = 0; i < QMF_WIN_LEN - 1; i++) { |
1490 | 0 | FDKmemcpy( |
1491 | 0 | hQmfTransposer->qmfInBufReal_F[i], |
1492 | 0 | hQmfTransposer->qmfInBufReal_F[i + 1], |
1493 | 0 | sizeof(FIXP_DBL) * hQmfTransposer->HBEAnalysiscQMF.no_channels); |
1494 | 0 | FDKmemcpy( |
1495 | 0 | hQmfTransposer->qmfInBufImag_F[i], |
1496 | 0 | hQmfTransposer->qmfInBufImag_F[i + 1], |
1497 | 0 | sizeof(FIXP_DBL) * hQmfTransposer->HBEAnalysiscQMF.no_channels); |
1498 | 0 | } |
1499 | 0 | continue; |
1500 | 0 | } |
1501 | | |
1502 | 0 | for (stretch = 2; stretch <= hQmfTransposer->maxStretch; stretch++) { |
1503 | 0 | int start = slotOffset - winLength[stretch - 2] / 2; |
1504 | 0 | int stop = slotOffset + winLength[stretch - 2] / 2; |
1505 | |
|
1506 | 0 | FIXP_DBL factor = FL2FXCONST_DBL(1.f / 3.f); |
1507 | |
|
1508 | 0 | for (band = hQmfTransposer->xOverQmf[stretch - 2]; |
1509 | 0 | band < hQmfTransposer->xOverQmf[stretch - 1]; band++) { |
1510 | 0 | FIXP_DBL gammaCenterReal_m[2] = {(FIXP_DBL)0, (FIXP_DBL)0}, |
1511 | 0 | gammaCenterImag_m[2] = {(FIXP_DBL)0, (FIXP_DBL)0}; |
1512 | 0 | INT gammaCenter_e[2] = {0, 0}; |
1513 | |
|
1514 | 0 | FIXP_DBL gammaVecReal_m[2] = {(FIXP_DBL)0, (FIXP_DBL)0}, |
1515 | 0 | gammaVecImag_m[2] = {(FIXP_DBL)0, (FIXP_DBL)0}; |
1516 | 0 | INT gammaVec_e[2] = {0, 0}; |
1517 | |
|
1518 | 0 | FIXP_DBL wingain = (FIXP_DBL)0; |
1519 | |
|
1520 | 0 | gammaCenter_e[0] = |
1521 | 0 | SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); |
1522 | 0 | gammaCenter_e[1] = |
1523 | 0 | SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); |
1524 | | |
1525 | | /* interpolation filters for 3rd order */ |
1526 | 0 | sourceband = 2 * band / stretch - qmfOffset; |
1527 | 0 | FDK_ASSERT(sourceband >= 0); |
1528 | | |
1529 | | /* maximum gammaCenter_e == 20 */ |
1530 | 0 | calculateCenterFIXP( |
1531 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][sourceband], |
1532 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][sourceband], |
1533 | 0 | &gammaCenterReal_m[0], &gammaCenterImag_m[0], &gammaCenter_e[0], |
1534 | 0 | stretch, stretch - 2); |
1535 | |
|
1536 | 0 | if (stretch == 4) { |
1537 | 0 | r = band - 2 * (band / 2); |
1538 | 0 | sourceband += (r == 0) ? -1 : 1; |
1539 | 0 | pSlotStretch = slot_stretch4; |
1540 | 0 | factor = FL2FXCONST_DBL(2.f / 3.f); |
1541 | 0 | pFilt = filt_dummy; |
1542 | 0 | } else if (stretch == 2) { |
1543 | 0 | r = 0; |
1544 | 0 | sourceband = 2 * band / stretch - qmfOffset; |
1545 | 0 | pSlotStretch = slot_stretch2; |
1546 | 0 | factor = FL2FXCONST_DBL(1.f / 3.f); |
1547 | 0 | pFilt = filt_dummy; |
1548 | 0 | } else { |
1549 | 0 | r = 2 * band - 3 * (2 * band / 3); |
1550 | 0 | sourceband = 2 * band / stretch - qmfOffset; |
1551 | 0 | pSlotStretch = slot_stretch3; |
1552 | 0 | factor = FL2FXCONST_DBL(1.4142f / 3.0f); |
1553 | 0 | pFilt = filt_stretch3; |
1554 | 0 | } |
1555 | |
|
1556 | 0 | if (r == 2) { |
1557 | 0 | calculateCenterFIXP( |
1558 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][sourceband + 1], |
1559 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][sourceband + 1], |
1560 | 0 | &gammaCenterReal_m[1], &gammaCenterImag_m[1], &gammaCenter_e[1], |
1561 | 0 | stretch, stretch - 2); |
1562 | |
|
1563 | 0 | factor = FL2FXCONST_DBL(1.4142f / 6.0f); |
1564 | 0 | } |
1565 | |
|
1566 | 0 | if (r == 2) { |
1567 | 0 | for (k = start; k < stop; k++) { |
1568 | 0 | gammaVecReal_m[0] = |
1569 | 0 | hQmfTransposer->qmfInBufReal_F[pSlotStretch[k]][sourceband]; |
1570 | 0 | gammaVecReal_m[1] = |
1571 | 0 | hQmfTransposer->qmfInBufReal_F[pSlotStretch[k]][sourceband + 1]; |
1572 | 0 | gammaVecImag_m[0] = |
1573 | 0 | hQmfTransposer->qmfInBufImag_F[pSlotStretch[k]][sourceband]; |
1574 | 0 | gammaVecImag_m[1] = |
1575 | 0 | hQmfTransposer->qmfInBufImag_F[pSlotStretch[k]][sourceband + 1]; |
1576 | 0 | gammaVec_e[0] = gammaVec_e[1] = |
1577 | 0 | SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); |
1578 | |
|
1579 | 0 | if (pFilt[k] == 1) { |
1580 | 0 | FIXP_DBL tmpRealF = gammaVecReal_m[0], tmpImagF; |
1581 | 0 | gammaVecReal_m[0] = |
1582 | 0 | (fMult(gammaVecReal_m[0], hintReal_F[sourceband % 4][1]) - |
1583 | 0 | fMult(gammaVecImag_m[0], |
1584 | 0 | hintReal_F[(sourceband + 3) % 4][1])) >> |
1585 | 0 | 1; /* sum should be <= 1 because of sin/cos multiplication */ |
1586 | 0 | gammaVecImag_m[0] = |
1587 | 0 | (fMult(tmpRealF, hintReal_F[(sourceband + 3) % 4][1]) + |
1588 | 0 | fMult(gammaVecImag_m[0], hintReal_F[sourceband % 4][1])) >> |
1589 | 0 | 1; /* sum should be <= 1 because of sin/cos multiplication */ |
1590 | |
|
1591 | 0 | tmpRealF = hQmfTransposer |
1592 | 0 | ->qmfInBufReal_F[pSlotStretch[k] + 1][sourceband]; |
1593 | 0 | tmpImagF = hQmfTransposer |
1594 | 0 | ->qmfInBufImag_F[pSlotStretch[k] + 1][sourceband]; |
1595 | |
|
1596 | 0 | gammaVecReal_m[0] += |
1597 | 0 | (fMult(tmpRealF, hintReal_F[sourceband % 4][1]) - |
1598 | 0 | fMult(tmpImagF, hintReal_F[(sourceband + 1) % 4][1])) >> |
1599 | 0 | 1; /* sum should be <= 1 because of sin/cos multiplication */ |
1600 | 0 | gammaVecImag_m[0] += |
1601 | 0 | (fMult(tmpRealF, hintReal_F[(sourceband + 1) % 4][1]) + |
1602 | 0 | fMult(tmpImagF, hintReal_F[sourceband % 4][1])) >> |
1603 | 0 | 1; /* sum should be <= 1 because of sin/cos multiplication */ |
1604 | 0 | gammaVec_e[0]++; |
1605 | |
|
1606 | 0 | tmpRealF = gammaVecReal_m[1]; |
1607 | |
|
1608 | 0 | gammaVecReal_m[1] = |
1609 | 0 | (fMult(gammaVecReal_m[1], hintReal_F[sourceband % 4][2]) - |
1610 | 0 | fMult(gammaVecImag_m[1], |
1611 | 0 | hintReal_F[(sourceband + 3) % 4][2])) >> |
1612 | 0 | 1; |
1613 | 0 | gammaVecImag_m[1] = |
1614 | 0 | (fMult(tmpRealF, hintReal_F[(sourceband + 3) % 4][2]) + |
1615 | 0 | fMult(gammaVecImag_m[1], hintReal_F[sourceband % 4][2])) >> |
1616 | 0 | 1; |
1617 | |
|
1618 | 0 | tmpRealF = |
1619 | 0 | hQmfTransposer |
1620 | 0 | ->qmfInBufReal_F[pSlotStretch[k] + 1][sourceband + 1]; |
1621 | 0 | tmpImagF = |
1622 | 0 | hQmfTransposer |
1623 | 0 | ->qmfInBufImag_F[pSlotStretch[k] + 1][sourceband + 1]; |
1624 | |
|
1625 | 0 | gammaVecReal_m[1] += |
1626 | 0 | (fMult(tmpRealF, hintReal_F[sourceband % 4][2]) - |
1627 | 0 | fMult(tmpImagF, hintReal_F[(sourceband + 1) % 4][2])) >> |
1628 | 0 | 1; |
1629 | 0 | gammaVecImag_m[1] += |
1630 | 0 | (fMult(tmpRealF, hintReal_F[(sourceband + 1) % 4][2]) + |
1631 | 0 | fMult(tmpImagF, hintReal_F[sourceband % 4][2])) >> |
1632 | 0 | 1; |
1633 | 0 | gammaVec_e[1]++; |
1634 | 0 | } |
1635 | |
|
1636 | 0 | addHighBandPart(gammaVecReal_m[1], gammaVecImag_m[1], gammaVec_e[1], |
1637 | 0 | factor, gammaCenterReal_m[0], gammaCenterImag_m[0], |
1638 | 0 | gammaCenter_e[0], stretch, scale_factor_hbe, |
1639 | 0 | &hQmfTransposer->qmfHBEBufReal_F[k][band], |
1640 | 0 | &hQmfTransposer->qmfHBEBufImag_F[k][band]); |
1641 | |
|
1642 | 0 | addHighBandPart(gammaVecReal_m[0], gammaVecImag_m[0], gammaVec_e[0], |
1643 | 0 | factor, gammaCenterReal_m[1], gammaCenterImag_m[1], |
1644 | 0 | gammaCenter_e[1], stretch, scale_factor_hbe, |
1645 | 0 | &hQmfTransposer->qmfHBEBufReal_F[k][band], |
1646 | 0 | &hQmfTransposer->qmfHBEBufImag_F[k][band]); |
1647 | 0 | } |
1648 | 0 | } else { |
1649 | 0 | for (k = start; k < stop; k++) { |
1650 | 0 | gammaVecReal_m[0] = |
1651 | 0 | hQmfTransposer->qmfInBufReal_F[pSlotStretch[k]][sourceband]; |
1652 | 0 | gammaVecImag_m[0] = |
1653 | 0 | hQmfTransposer->qmfInBufImag_F[pSlotStretch[k]][sourceband]; |
1654 | 0 | gammaVec_e[0] = |
1655 | 0 | SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); |
1656 | |
|
1657 | 0 | if (pFilt[k] == 1) { |
1658 | 0 | FIXP_DBL tmpRealF = gammaVecReal_m[0], tmpImagF; |
1659 | 0 | gammaVecReal_m[0] = |
1660 | 0 | (fMult(gammaVecReal_m[0], hintReal_F[sourceband % 4][1]) - |
1661 | 0 | fMult(gammaVecImag_m[0], |
1662 | 0 | hintReal_F[(sourceband + 3) % 4][1])) >> |
1663 | 0 | 1; /* sum should be <= 1 because of sin/cos multiplication */ |
1664 | 0 | gammaVecImag_m[0] = |
1665 | 0 | (fMult(tmpRealF, hintReal_F[(sourceband + 3) % 4][1]) + |
1666 | 0 | fMult(gammaVecImag_m[0], hintReal_F[sourceband % 4][1])) >> |
1667 | 0 | 1; /* sum should be <= 1 because of sin/cos multiplication */ |
1668 | |
|
1669 | 0 | tmpRealF = hQmfTransposer |
1670 | 0 | ->qmfInBufReal_F[pSlotStretch[k] + 1][sourceband]; |
1671 | 0 | tmpImagF = hQmfTransposer |
1672 | 0 | ->qmfInBufImag_F[pSlotStretch[k] + 1][sourceband]; |
1673 | |
|
1674 | 0 | gammaVecReal_m[0] += |
1675 | 0 | (fMult(tmpRealF, hintReal_F[sourceband % 4][1]) - |
1676 | 0 | fMult(tmpImagF, hintReal_F[(sourceband + 1) % 4][1])) >> |
1677 | 0 | 1; /* sum should be <= 1 because of sin/cos multiplication */ |
1678 | 0 | gammaVecImag_m[0] += |
1679 | 0 | (fMult(tmpRealF, hintReal_F[(sourceband + 1) % 4][1]) + |
1680 | 0 | fMult(tmpImagF, hintReal_F[sourceband % 4][1])) >> |
1681 | 0 | 1; /* sum should be <= 1 because of sin/cos multiplication */ |
1682 | 0 | gammaVec_e[0]++; |
1683 | 0 | } |
1684 | |
|
1685 | 0 | addHighBandPart(gammaVecReal_m[0], gammaVecImag_m[0], gammaVec_e[0], |
1686 | 0 | factor, gammaCenterReal_m[0], gammaCenterImag_m[0], |
1687 | 0 | gammaCenter_e[0], stretch, scale_factor_hbe, |
1688 | 0 | &hQmfTransposer->qmfHBEBufReal_F[k][band], |
1689 | 0 | &hQmfTransposer->qmfHBEBufImag_F[k][band]); |
1690 | 0 | } |
1691 | 0 | } |
1692 | | |
1693 | | /* pitchInBins is given with the resolution of a 768 bins FFT and we |
1694 | | * need 64 QMF units so factor 768/64 = 12 */ |
1695 | 0 | if (pitchInBins >= pmin * (1 + bSbr41)) { |
1696 | 0 | int tr, ti1, ti2, mTr = 0, ts1 = 0, ts2 = 0, mVal_e = 0, temp_e = 0; |
1697 | 0 | int sqmag0_e = |
1698 | 0 | SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); |
1699 | |
|
1700 | 0 | FIXP_DBL mVal_F = FL2FXCONST_DBL(0.f), sqmag0_F, sqmag1_F, sqmag2_F, |
1701 | 0 | temp_F, f1_F; /* all equal exponent */ |
1702 | 0 | sign = -1; |
1703 | |
|
1704 | 0 | sourceband = 2 * band / stretch - qmfOffset; /* consistent with the |
1705 | | already computed for |
1706 | | stretch = 3,4. */ |
1707 | 0 | FDK_ASSERT(sourceband >= 0); |
1708 | | |
1709 | 0 | FIXP_DBL sqmag0R_F = |
1710 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][sourceband]; |
1711 | 0 | FIXP_DBL sqmag0I_F = |
1712 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][sourceband]; |
1713 | 0 | scaleUp(&sqmag0R_F, &sqmag0I_F, &sqmag0_e); |
1714 | |
|
1715 | 0 | sqmag0_F = fPow2Div2(sqmag0R_F); |
1716 | 0 | sqmag0_F += fPow2Div2(sqmag0I_F); |
1717 | 0 | sqmag0_e = 2 * sqmag0_e + 1; |
1718 | |
|
1719 | 0 | for (tr = 1; tr < stretch; tr++) { |
1720 | 0 | int sqmag1_e = |
1721 | 0 | SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); |
1722 | 0 | int sqmag2_e = |
1723 | 0 | SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); |
1724 | |
|
1725 | 0 | FIXP_DBL tmp_band = band_F[band]; |
1726 | 0 | FIXP_DBL tr_p = |
1727 | 0 | fMult(p_F[pitchInBins] >> bSbr41, tr_str[tr - 1]); /* scale 7 */ |
1728 | 0 | f1_F = |
1729 | 0 | fMult(tmp_band - tr_p, stretchfac[stretch - 2]); /* scale 7 */ |
1730 | 0 | ti1 = (INT)(f1_F >> (DFRACT_BITS - 1 - 7)) - qmfOffset; |
1731 | 0 | ti2 = (INT)(((f1_F) + ((p_F[pitchInBins] >> bSbr41) >> 2)) >> |
1732 | 0 | (DFRACT_BITS - 1 - 7)) - |
1733 | 0 | qmfOffset; |
1734 | |
|
1735 | 0 | if (ti1 >= 0 && ti2 < 2 * hQmfTransposer->synthSize) { |
1736 | 0 | FIXP_DBL sqmag1R_F = |
1737 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][ti1]; |
1738 | 0 | FIXP_DBL sqmag1I_F = |
1739 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][ti1]; |
1740 | 0 | scaleUp(&sqmag1R_F, &sqmag1I_F, &sqmag1_e); |
1741 | 0 | sqmag1_F = fPow2Div2(sqmag1R_F); |
1742 | 0 | sqmag1_F += fPow2Div2(sqmag1I_F); |
1743 | 0 | sqmag1_e = 2 * sqmag1_e + 1; |
1744 | |
|
1745 | 0 | FIXP_DBL sqmag2R_F = |
1746 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][ti2]; |
1747 | 0 | FIXP_DBL sqmag2I_F = |
1748 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][ti2]; |
1749 | 0 | scaleUp(&sqmag2R_F, &sqmag2I_F, &sqmag2_e); |
1750 | 0 | sqmag2_F = fPow2Div2(sqmag2R_F); |
1751 | 0 | sqmag2_F += fPow2Div2(sqmag2I_F); |
1752 | 0 | sqmag2_e = 2 * sqmag2_e + 1; |
1753 | |
|
1754 | 0 | int shift1 = fMin(fMax(sqmag1_e, sqmag2_e) - sqmag1_e, 31); |
1755 | 0 | int shift2 = fMin(fMax(sqmag1_e, sqmag2_e) - sqmag2_e, 31); |
1756 | |
|
1757 | 0 | temp_F = fMin((sqmag1_F >> shift1), (sqmag2_F >> shift2)); |
1758 | 0 | temp_e = fMax(sqmag1_e, sqmag2_e); |
1759 | |
|
1760 | 0 | int shift3 = fMin(fMax(temp_e, mVal_e) - temp_e, 31); |
1761 | 0 | int shift4 = fMin(fMax(temp_e, mVal_e) - mVal_e, 31); |
1762 | |
|
1763 | 0 | if ((temp_F >> shift3) > (mVal_F >> shift4)) { |
1764 | 0 | mVal_F = temp_F; |
1765 | 0 | mVal_e = temp_e; /* equals sqmag2_e + shift2 */ |
1766 | 0 | mTr = tr; |
1767 | 0 | ts1 = ti1; |
1768 | 0 | ts2 = ti2; |
1769 | 0 | } |
1770 | 0 | } |
1771 | 0 | } |
1772 | |
|
1773 | 0 | int shift1 = fMin(fMax(sqmag0_e, mVal_e) - sqmag0_e, 31); |
1774 | 0 | int shift2 = fMin(fMax(sqmag0_e, mVal_e) - mVal_e, 31); |
1775 | |
|
1776 | 0 | if ((mVal_F >> shift2) > (sqmag0_F >> shift1) && ts1 >= 0 && |
1777 | 0 | ts2 < 2 * hQmfTransposer->synthSize) { |
1778 | 0 | INT gammaOut_e[2]; |
1779 | 0 | FIXP_DBL gammaOutReal_m[2], gammaOutImag_m[2]; |
1780 | 0 | FIXP_DBL tmpReal_m = (FIXP_DBL)0, tmpImag_m = (FIXP_DBL)0; |
1781 | |
|
1782 | 0 | int Tcenter, Tvec; |
1783 | |
|
1784 | 0 | Tcenter = stretch - mTr; /* default phase power parameters */ |
1785 | 0 | Tvec = mTr; |
1786 | 0 | switch (stretch) /* 2 tap block creation design depends on stretch |
1787 | | order */ |
1788 | 0 | { |
1789 | 0 | case 2: |
1790 | 0 | wingain = |
1791 | 0 | FL2FXCONST_DBL(5.f / 12.f); /* sum of taps divided by two */ |
1792 | |
|
1793 | 0 | if (hQmfTransposer->bXProducts[0]) { |
1794 | 0 | gammaCenterReal_m[0] = |
1795 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][ts1]; |
1796 | 0 | gammaCenterImag_m[0] = |
1797 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][ts1]; |
1798 | |
|
1799 | 0 | for (k = 0; k < 2; k++) { |
1800 | 0 | gammaVecReal_m[k] = |
1801 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset - 1 + k][ts2]; |
1802 | 0 | gammaVecImag_m[k] = |
1803 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset - 1 + k][ts2]; |
1804 | 0 | } |
1805 | |
|
1806 | 0 | gammaCenter_e[0] = SCALE2EXP( |
1807 | 0 | -hQmfTransposer->HBEAnalysiscQMF.outScalefactor); |
1808 | 0 | gammaVec_e[0] = gammaVec_e[1] = SCALE2EXP( |
1809 | 0 | -hQmfTransposer->HBEAnalysiscQMF.outScalefactor); |
1810 | 0 | } |
1811 | 0 | break; |
1812 | | |
1813 | 0 | case 4: |
1814 | 0 | wingain = |
1815 | 0 | FL2FXCONST_DBL(6.f / 12.f); /* sum of taps divided by two */ |
1816 | 0 | if (hQmfTransposer->bXProducts[2]) { |
1817 | 0 | if (mTr == 1) { |
1818 | 0 | gammaCenterReal_m[0] = |
1819 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][ts1]; |
1820 | 0 | gammaCenterImag_m[0] = |
1821 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][ts1]; |
1822 | |
|
1823 | 0 | for (k = 0; k < 2; k++) { |
1824 | 0 | gammaVecReal_m[k] = |
1825 | 0 | hQmfTransposer |
1826 | 0 | ->qmfInBufReal_F[slotOffset + 2 * (k - 1)][ts2]; |
1827 | 0 | gammaVecImag_m[k] = |
1828 | 0 | hQmfTransposer |
1829 | 0 | ->qmfInBufImag_F[slotOffset + 2 * (k - 1)][ts2]; |
1830 | 0 | } |
1831 | 0 | } else if (mTr == 2) { |
1832 | 0 | gammaCenterReal_m[0] = |
1833 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][ts1]; |
1834 | 0 | gammaCenterImag_m[0] = |
1835 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][ts1]; |
1836 | |
|
1837 | 0 | for (k = 0; k < 2; k++) { |
1838 | 0 | gammaVecReal_m[k] = |
1839 | 0 | hQmfTransposer |
1840 | 0 | ->qmfInBufReal_F[slotOffset + (k - 1)][ts2]; |
1841 | 0 | gammaVecImag_m[k] = |
1842 | 0 | hQmfTransposer |
1843 | 0 | ->qmfInBufImag_F[slotOffset + (k - 1)][ts2]; |
1844 | 0 | } |
1845 | 0 | } else /* (mTr == 3) */ |
1846 | 0 | { |
1847 | 0 | sign = 1; |
1848 | 0 | Tcenter = mTr; /* opposite phase power parameters as ts2 is |
1849 | | center */ |
1850 | 0 | Tvec = stretch - mTr; |
1851 | |
|
1852 | 0 | gammaCenterReal_m[0] = |
1853 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][ts2]; |
1854 | 0 | gammaCenterImag_m[0] = |
1855 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][ts2]; |
1856 | |
|
1857 | 0 | for (k = 0; k < 2; k++) { |
1858 | 0 | gammaVecReal_m[k] = |
1859 | 0 | hQmfTransposer |
1860 | 0 | ->qmfInBufReal_F[slotOffset + 2 * (k - 1)][ts1]; |
1861 | 0 | gammaVecImag_m[k] = |
1862 | 0 | hQmfTransposer |
1863 | 0 | ->qmfInBufImag_F[slotOffset + 2 * (k - 1)][ts1]; |
1864 | 0 | } |
1865 | 0 | } |
1866 | |
|
1867 | 0 | gammaCenter_e[0] = SCALE2EXP( |
1868 | 0 | -hQmfTransposer->HBEAnalysiscQMF.outScalefactor); |
1869 | 0 | gammaVec_e[0] = gammaVec_e[1] = SCALE2EXP( |
1870 | 0 | -hQmfTransposer->HBEAnalysiscQMF.outScalefactor); |
1871 | 0 | } |
1872 | 0 | break; |
1873 | | |
1874 | 0 | case 3: |
1875 | 0 | wingain = FL2FXCONST_DBL(5.6568f / |
1876 | 0 | 12.f); /* sum of taps divided by two */ |
1877 | |
|
1878 | 0 | if (hQmfTransposer->bXProducts[1]) { |
1879 | 0 | FIXP_DBL tmpReal_F, tmpImag_F; |
1880 | 0 | if (mTr == 1) { |
1881 | 0 | gammaCenterReal_m[0] = |
1882 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][ts1]; |
1883 | 0 | gammaCenterImag_m[0] = |
1884 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][ts1]; |
1885 | 0 | gammaVecReal_m[1] = |
1886 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][ts2]; |
1887 | 0 | gammaVecImag_m[1] = |
1888 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][ts2]; |
1889 | |
|
1890 | 0 | addrshift = -2; |
1891 | 0 | tmpReal_F = |
1892 | 0 | hQmfTransposer |
1893 | 0 | ->qmfInBufReal_F[addrshift + slotOffset][ts2]; |
1894 | 0 | tmpImag_F = |
1895 | 0 | hQmfTransposer |
1896 | 0 | ->qmfInBufImag_F[addrshift + slotOffset][ts2]; |
1897 | |
|
1898 | 0 | gammaVecReal_m[0] = |
1899 | 0 | (fMult(factors[ts2 % 4], tmpReal_F) - |
1900 | 0 | fMult(factors[(ts2 + 3) % 4], tmpImag_F)) >> |
1901 | 0 | 1; |
1902 | 0 | gammaVecImag_m[0] = |
1903 | 0 | (fMult(factors[(ts2 + 3) % 4], tmpReal_F) + |
1904 | 0 | fMult(factors[ts2 % 4], tmpImag_F)) >> |
1905 | 0 | 1; |
1906 | |
|
1907 | 0 | tmpReal_F = |
1908 | 0 | hQmfTransposer |
1909 | 0 | ->qmfInBufReal_F[addrshift + 1 + slotOffset][ts2]; |
1910 | 0 | tmpImag_F = |
1911 | 0 | hQmfTransposer |
1912 | 0 | ->qmfInBufImag_F[addrshift + 1 + slotOffset][ts2]; |
1913 | |
|
1914 | 0 | gammaVecReal_m[0] += |
1915 | 0 | (fMult(factors[ts2 % 4], tmpReal_F) - |
1916 | 0 | fMult(factors[(ts2 + 1) % 4], tmpImag_F)) >> |
1917 | 0 | 1; |
1918 | 0 | gammaVecImag_m[0] += |
1919 | 0 | (fMult(factors[(ts2 + 1) % 4], tmpReal_F) + |
1920 | 0 | fMult(factors[ts2 % 4], tmpImag_F)) >> |
1921 | 0 | 1; |
1922 | |
|
1923 | 0 | } else /* (mTr == 2) */ |
1924 | 0 | { |
1925 | 0 | sign = 1; |
1926 | 0 | Tcenter = mTr; /* opposite phase power parameters as ts2 is |
1927 | | center */ |
1928 | 0 | Tvec = stretch - mTr; |
1929 | |
|
1930 | 0 | gammaCenterReal_m[0] = |
1931 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][ts2]; |
1932 | 0 | gammaCenterImag_m[0] = |
1933 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][ts2]; |
1934 | 0 | gammaVecReal_m[1] = |
1935 | 0 | hQmfTransposer->qmfInBufReal_F[slotOffset][ts1]; |
1936 | 0 | gammaVecImag_m[1] = |
1937 | 0 | hQmfTransposer->qmfInBufImag_F[slotOffset][ts1]; |
1938 | |
|
1939 | 0 | addrshift = -2; |
1940 | 0 | tmpReal_F = |
1941 | 0 | hQmfTransposer |
1942 | 0 | ->qmfInBufReal_F[addrshift + slotOffset][ts1]; |
1943 | 0 | tmpImag_F = |
1944 | 0 | hQmfTransposer |
1945 | 0 | ->qmfInBufImag_F[addrshift + slotOffset][ts1]; |
1946 | |
|
1947 | 0 | gammaVecReal_m[0] = |
1948 | 0 | (fMult(factors[ts1 % 4], tmpReal_F) - |
1949 | 0 | fMult(factors[(ts1 + 3) % 4], tmpImag_F)) >> |
1950 | 0 | 1; |
1951 | 0 | gammaVecImag_m[0] = |
1952 | 0 | (fMult(factors[(ts1 + 3) % 4], tmpReal_F) + |
1953 | 0 | fMult(factors[ts1 % 4], tmpImag_F)) >> |
1954 | 0 | 1; |
1955 | |
|
1956 | 0 | tmpReal_F = |
1957 | 0 | hQmfTransposer |
1958 | 0 | ->qmfInBufReal_F[addrshift + 1 + slotOffset][ts1]; |
1959 | 0 | tmpImag_F = |
1960 | 0 | hQmfTransposer |
1961 | 0 | ->qmfInBufImag_F[addrshift + 1 + slotOffset][ts1]; |
1962 | |
|
1963 | 0 | gammaVecReal_m[0] += |
1964 | 0 | (fMult(factors[ts1 % 4], tmpReal_F) - |
1965 | 0 | fMult(factors[(ts1 + 1) % 4], tmpImag_F)) >> |
1966 | 0 | 1; |
1967 | 0 | gammaVecImag_m[0] += |
1968 | 0 | (fMult(factors[(ts1 + 1) % 4], tmpReal_F) + |
1969 | 0 | fMult(factors[ts1 % 4], tmpImag_F)) >> |
1970 | 0 | 1; |
1971 | 0 | } |
1972 | |
|
1973 | 0 | gammaCenter_e[0] = gammaVec_e[1] = SCALE2EXP( |
1974 | 0 | -hQmfTransposer->HBEAnalysiscQMF.outScalefactor); |
1975 | 0 | gammaVec_e[0] = |
1976 | 0 | SCALE2EXP( |
1977 | 0 | -hQmfTransposer->HBEAnalysiscQMF.outScalefactor) + |
1978 | 0 | 1; |
1979 | 0 | } |
1980 | 0 | break; |
1981 | 0 | default: |
1982 | 0 | FDK_ASSERT(0); |
1983 | 0 | break; |
1984 | 0 | } /* stretch cases */ |
1985 | | |
1986 | | /* parameter controlled phase modification parts */ |
1987 | | /* maximum *_e == 20 */ |
1988 | 0 | calculateCenterFIXP(gammaCenterReal_m[0], gammaCenterImag_m[0], |
1989 | 0 | &gammaCenterReal_m[0], &gammaCenterImag_m[0], |
1990 | 0 | &gammaCenter_e[0], stretch, Tcenter - 1); |
1991 | 0 | calculateCenterFIXP(gammaVecReal_m[0], gammaVecImag_m[0], |
1992 | 0 | &gammaVecReal_m[0], &gammaVecImag_m[0], |
1993 | 0 | &gammaVec_e[0], stretch, Tvec - 1); |
1994 | 0 | calculateCenterFIXP(gammaVecReal_m[1], gammaVecImag_m[1], |
1995 | 0 | &gammaVecReal_m[1], &gammaVecImag_m[1], |
1996 | 0 | &gammaVec_e[1], stretch, Tvec - 1); |
1997 | | |
1998 | | /* Final multiplication of prepared parts */ |
1999 | 0 | for (k = 0; k < 2; k++) { |
2000 | 0 | gammaOutReal_m[k] = |
2001 | 0 | fMultDiv2(gammaVecReal_m[k], gammaCenterReal_m[0]) - |
2002 | 0 | fMultDiv2(gammaVecImag_m[k], gammaCenterImag_m[0]); |
2003 | 0 | gammaOutImag_m[k] = |
2004 | 0 | fMultDiv2(gammaVecReal_m[k], gammaCenterImag_m[0]) + |
2005 | 0 | fMultDiv2(gammaVecImag_m[k], gammaCenterReal_m[0]); |
2006 | 0 | gammaOut_e[k] = gammaCenter_e[0] + gammaVec_e[k] + 1; |
2007 | 0 | } |
2008 | |
|
2009 | 0 | scaleUp(&gammaOutReal_m[0], &gammaOutImag_m[0], &gammaOut_e[0]); |
2010 | 0 | scaleUp(&gammaOutReal_m[1], &gammaOutImag_m[1], &gammaOut_e[1]); |
2011 | 0 | FDK_ASSERT(gammaOut_e[0] >= 0); |
2012 | 0 | FDK_ASSERT(gammaOut_e[0] < 32); |
2013 | | |
2014 | 0 | tmpReal_m = gammaOutReal_m[0]; |
2015 | 0 | tmpImag_m = gammaOutImag_m[0]; |
2016 | |
|
2017 | 0 | INT modstretch4 = ((stretch == 4) && (mTr == 2)); |
2018 | |
|
2019 | 0 | FIXP_DBL cos_twid = twid_m_new[stretch - 2 - modstretch4][0]; |
2020 | 0 | FIXP_DBL sin_twid = sign * twid_m_new[stretch - 2 - modstretch4][1]; |
2021 | |
|
2022 | 0 | gammaOutReal_m[0] = |
2023 | 0 | fMult(tmpReal_m, cos_twid) - |
2024 | 0 | fMult(tmpImag_m, sin_twid); /* sum should be <= 1 because of |
2025 | | sin/cos multiplication */ |
2026 | 0 | gammaOutImag_m[0] = |
2027 | 0 | fMult(tmpImag_m, cos_twid) + |
2028 | 0 | fMult(tmpReal_m, sin_twid); /* sum should be <= 1 because of |
2029 | | sin/cos multiplication */ |
2030 | | |
2031 | | /* wingain */ |
2032 | 0 | for (k = 0; k < 2; k++) { |
2033 | 0 | gammaOutReal_m[k] = (fMult(gammaOutReal_m[k], wingain) << 1); |
2034 | 0 | gammaOutImag_m[k] = (fMult(gammaOutImag_m[k], wingain) << 1); |
2035 | 0 | } |
2036 | |
|
2037 | 0 | gammaOutReal_m[1] >>= 1; |
2038 | 0 | gammaOutImag_m[1] >>= 1; |
2039 | 0 | gammaOut_e[0] += 2; |
2040 | 0 | gammaOut_e[1] += 2; |
2041 | | |
2042 | | /* OLA including window scaling by wingain/3 */ |
2043 | 0 | for (k = 0; k < 2; k++) /* need k=1 to correspond to |
2044 | | grainModImag[slotOffset] -> out to |
2045 | | j*2+(slotOffset-offset) */ |
2046 | 0 | { |
2047 | 0 | hQmfTransposer->qmfHBEBufReal_F[(k + slotOffset - 1)][band] += |
2048 | 0 | gammaOutReal_m[k] >> (scale_factor_hbe - gammaOut_e[k]); |
2049 | 0 | hQmfTransposer->qmfHBEBufImag_F[(k + slotOffset - 1)][band] += |
2050 | 0 | gammaOutImag_m[k] >> (scale_factor_hbe - gammaOut_e[k]); |
2051 | 0 | } |
2052 | 0 | } /* mVal > qThrQMF * qThrQMF * sqmag0 && ts1 > 0 && ts2 < 64 */ |
2053 | 0 | } /* p >= pmin */ |
2054 | 0 | } /* for band */ |
2055 | 0 | } /* for stretch */ |
2056 | | |
2057 | 0 | for (i = 0; i < QMF_WIN_LEN - 1; i++) { |
2058 | 0 | FDKmemcpy(hQmfTransposer->qmfInBufReal_F[i], |
2059 | 0 | hQmfTransposer->qmfInBufReal_F[i + 1], |
2060 | 0 | sizeof(FIXP_DBL) * hQmfTransposer->HBEAnalysiscQMF.no_channels); |
2061 | 0 | FDKmemcpy(hQmfTransposer->qmfInBufImag_F[i], |
2062 | 0 | hQmfTransposer->qmfInBufImag_F[i + 1], |
2063 | 0 | sizeof(FIXP_DBL) * hQmfTransposer->HBEAnalysiscQMF.no_channels); |
2064 | 0 | } |
2065 | |
|
2066 | 0 | if (keepStatesSyncedMode != KEEP_STATES_SYNCED_NOOUT) { |
2067 | 0 | if (2 * j >= offset) { |
2068 | | /* copy first two slots of internal buffer to output */ |
2069 | 0 | if (keepStatesSyncedMode == KEEP_STATES_SYNCED_OUTDIFF) { |
2070 | 0 | for (i = 0; i < 2; i++) { |
2071 | 0 | FDKmemcpy(&ppQmfBufferOutReal_F[2 * j - offset + i] |
2072 | 0 | [hQmfTransposer->xOverQmf[0]], |
2073 | 0 | &hQmfTransposer |
2074 | 0 | ->qmfHBEBufReal_F[i][hQmfTransposer->xOverQmf[0]], |
2075 | 0 | (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * |
2076 | 0 | sizeof(FIXP_DBL)); |
2077 | 0 | FDKmemcpy(&ppQmfBufferOutImag_F[2 * j - offset + i] |
2078 | 0 | [hQmfTransposer->xOverQmf[0]], |
2079 | 0 | &hQmfTransposer |
2080 | 0 | ->qmfHBEBufImag_F[i][hQmfTransposer->xOverQmf[0]], |
2081 | 0 | (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * |
2082 | 0 | sizeof(FIXP_DBL)); |
2083 | 0 | } |
2084 | 0 | } else { |
2085 | 0 | for (i = 0; i < 2; i++) { |
2086 | 0 | FDKmemcpy(&ppQmfBufferOutReal_F[2 * j + i + ov_len] |
2087 | 0 | [hQmfTransposer->xOverQmf[0]], |
2088 | 0 | &hQmfTransposer |
2089 | 0 | ->qmfHBEBufReal_F[i][hQmfTransposer->xOverQmf[0]], |
2090 | 0 | (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * |
2091 | 0 | sizeof(FIXP_DBL)); |
2092 | 0 | FDKmemcpy(&ppQmfBufferOutImag_F[2 * j + i + ov_len] |
2093 | 0 | [hQmfTransposer->xOverQmf[0]], |
2094 | 0 | &hQmfTransposer |
2095 | 0 | ->qmfHBEBufImag_F[i][hQmfTransposer->xOverQmf[0]], |
2096 | 0 | (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * |
2097 | 0 | sizeof(FIXP_DBL)); |
2098 | 0 | } |
2099 | 0 | } |
2100 | 0 | } |
2101 | 0 | } |
2102 | | |
2103 | | /* move slots up */ |
2104 | 0 | for (i = 0; i < HBE_MAX_OUT_SLOTS - 2; i++) { |
2105 | 0 | FDKmemcpy( |
2106 | 0 | &hQmfTransposer->qmfHBEBufReal_F[i][hQmfTransposer->xOverQmf[0]], |
2107 | 0 | &hQmfTransposer->qmfHBEBufReal_F[i + 2][hQmfTransposer->xOverQmf[0]], |
2108 | 0 | (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * |
2109 | 0 | sizeof(FIXP_DBL)); |
2110 | 0 | FDKmemcpy( |
2111 | 0 | &hQmfTransposer->qmfHBEBufImag_F[i][hQmfTransposer->xOverQmf[0]], |
2112 | 0 | &hQmfTransposer->qmfHBEBufImag_F[i + 2][hQmfTransposer->xOverQmf[0]], |
2113 | 0 | (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * |
2114 | 0 | sizeof(FIXP_DBL)); |
2115 | 0 | } |
2116 | | |
2117 | | /* finally set last two slot to zero */ |
2118 | 0 | for (i = 0; i < 2; i++) { |
2119 | 0 | FDKmemset(&hQmfTransposer->qmfHBEBufReal_F[HBE_MAX_OUT_SLOTS - 1 - i] |
2120 | 0 | [hQmfTransposer->xOverQmf[0]], |
2121 | 0 | 0, |
2122 | 0 | (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * |
2123 | 0 | sizeof(FIXP_DBL)); |
2124 | 0 | FDKmemset(&hQmfTransposer->qmfHBEBufImag_F[HBE_MAX_OUT_SLOTS - 1 - i] |
2125 | 0 | [hQmfTransposer->xOverQmf[0]], |
2126 | 0 | 0, |
2127 | 0 | (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * |
2128 | 0 | sizeof(FIXP_DBL)); |
2129 | 0 | } |
2130 | 0 | } /* qmfVocoderColsIn */ |
2131 | | |
2132 | 0 | if (keepStatesSyncedMode != KEEP_STATES_SYNCED_NOOUT) { |
2133 | 0 | if (keepStatesSyncedMode == KEEP_STATES_SYNCED_OUTDIFF) { |
2134 | 0 | for (i = 0; i < ov_len + LPC_ORDER; i++) { |
2135 | 0 | for (band = hQmfTransposer->startBand; band < hQmfTransposer->stopBand; |
2136 | 0 | band++) { |
2137 | 0 | FIXP_DBL tmpR = ppQmfBufferOutReal_F[i][band]; |
2138 | 0 | FIXP_DBL tmpI = ppQmfBufferOutImag_F[i][band]; |
2139 | |
|
2140 | 0 | ppQmfBufferOutReal_F[i][band] = |
2141 | 0 | fMult(tmpR, cos_F[band]) - |
2142 | 0 | fMult(tmpI, (-cos_F[64 - band - 1])); /* sum should be <= 1 |
2143 | | because of sin/cos |
2144 | | multiplication */ |
2145 | 0 | ppQmfBufferOutImag_F[i][band] = |
2146 | 0 | fMult(tmpR, (-cos_F[64 - band - 1])) + |
2147 | 0 | fMult(tmpI, cos_F[band]); /* sum should by <= 1 because of sin/cos |
2148 | | multiplication */ |
2149 | 0 | } |
2150 | 0 | } |
2151 | 0 | } else { |
2152 | 0 | for (i = offset; i < hQmfTransposer->noCols; i++) { |
2153 | 0 | for (band = hQmfTransposer->startBand; band < hQmfTransposer->stopBand; |
2154 | 0 | band++) { |
2155 | 0 | FIXP_DBL tmpR = ppQmfBufferOutReal_F[i + ov_len][band]; |
2156 | 0 | FIXP_DBL tmpI = ppQmfBufferOutImag_F[i + ov_len][band]; |
2157 | |
|
2158 | 0 | ppQmfBufferOutReal_F[i + ov_len][band] = |
2159 | 0 | fMult(tmpR, cos_F[band]) - |
2160 | 0 | fMult(tmpI, (-cos_F[64 - band - 1])); /* sum should be <= 1 |
2161 | | because of sin/cos |
2162 | | multiplication */ |
2163 | 0 | ppQmfBufferOutImag_F[i + ov_len][band] = |
2164 | 0 | fMult(tmpR, (-cos_F[64 - band - 1])) + |
2165 | 0 | fMult(tmpI, cos_F[band]); /* sum should by <= 1 because of sin/cos |
2166 | | multiplication */ |
2167 | 0 | } |
2168 | 0 | } |
2169 | 0 | } |
2170 | 0 | } |
2171 | |
|
2172 | 0 | *scale_hb = EXP2SCALE(scale_factor_hbe); |
2173 | 0 | } |
2174 | | |
2175 | 0 | int* GetxOverBandQmfTransposer(HANDLE_HBE_TRANSPOSER hQmfTransposer) { |
2176 | 0 | if (hQmfTransposer) |
2177 | 0 | return hQmfTransposer->xOverQmf; |
2178 | 0 | else |
2179 | 0 | return NULL; |
2180 | 0 | } |
2181 | | |
2182 | 0 | int Get41SbrQmfTransposer(HANDLE_HBE_TRANSPOSER hQmfTransposer) { |
2183 | 0 | if (hQmfTransposer != NULL) |
2184 | 0 | return hQmfTransposer->bSbr41; |
2185 | 0 | else |
2186 | 0 | return 0; |
2187 | 0 | } |