/src/aac/libSBRdec/src/lpp_tran.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 Low Power Profile Transposer |
106 | | This module provides the transposer. The main entry point is lppTransposer(). |
107 | | The function generates high frequency content by copying data from the low |
108 | | band (provided by core codec) into the high band. This process is also |
109 | | referred to as "patching". The function also implements spectral whitening by |
110 | | means of inverse filtering based on LPC coefficients. |
111 | | |
112 | | Together with the QMF filterbank the transposer can be tested using a supplied |
113 | | test program. See main_audio.cpp for details. This module does use fractional |
114 | | arithmetic and the accuracy of the computations has an impact on the overall |
115 | | sound quality. The module also needs to take into account the different |
116 | | scaling of spectral data. |
117 | | |
118 | | \sa lppTransposer(), main_audio.cpp, sbr_scale.h, \ref documentationOverview |
119 | | */ |
120 | | |
121 | | #if __has_include(<android/ndk-version.h>) |
122 | | #include <android/ndk-version.h> |
123 | | #endif |
124 | | |
125 | | #if defined __ANDROID__ && !defined __ANDROID_NDK__ |
126 | | #include "log/log.h" |
127 | | #endif |
128 | | |
129 | | #include "lpp_tran.h" |
130 | | |
131 | | #include "sbr_ram.h" |
132 | | #include "sbr_rom.h" |
133 | | |
134 | | #include "genericStds.h" |
135 | | #include "autocorr2nd.h" |
136 | | |
137 | | #include "HFgen_preFlat.h" |
138 | | |
139 | 27.3M | #define LPC_SCALE_FACTOR 2 |
140 | | |
141 | | /*! |
142 | | * |
143 | | * \brief Get bandwidth expansion factor from filtering level |
144 | | * |
145 | | * Returns a filter parameter (bandwidth expansion factor) depending on |
146 | | * the desired filtering level signalled in the bitstream. |
147 | | * When switching the filtering level from LOW to OFF, an additional |
148 | | * level is being inserted to achieve a smooth transition. |
149 | | */ |
150 | | |
151 | | static FIXP_DBL mapInvfMode(INVF_MODE mode, INVF_MODE prevMode, |
152 | 787k | WHITENING_FACTORS whFactors) { |
153 | 787k | switch (mode) { |
154 | 265k | case INVF_LOW_LEVEL: |
155 | 265k | if (prevMode == INVF_OFF) |
156 | 22.1k | return whFactors.transitionLevel; |
157 | 243k | else |
158 | 243k | return whFactors.lowLevel; |
159 | | |
160 | 44.0k | case INVF_MID_LEVEL: |
161 | 44.0k | return whFactors.midLevel; |
162 | | |
163 | 97.1k | case INVF_HIGH_LEVEL: |
164 | 97.1k | return whFactors.highLevel; |
165 | | |
166 | 380k | default: |
167 | 380k | if (prevMode == INVF_LOW_LEVEL) |
168 | 15.2k | return whFactors.transitionLevel; |
169 | 365k | else |
170 | 365k | return whFactors.off; |
171 | 787k | } |
172 | 787k | } |
173 | | |
174 | | /*! |
175 | | * |
176 | | * \brief Perform inverse filtering level emphasis |
177 | | * |
178 | | * Retrieve bandwidth expansion factor and apply smoothing for each filter band |
179 | | * |
180 | | */ |
181 | | |
182 | | static void inverseFilteringLevelEmphasis( |
183 | | HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */ |
184 | | UCHAR nInvfBands, /*!< Number of bands for inverse filtering */ |
185 | | INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */ |
186 | | INVF_MODE *sbr_invf_mode_prev, /*!< Previous inverse filtering modes */ |
187 | | FIXP_DBL *bwVector /*!< Resulting filtering levels */ |
188 | 342k | ) { |
189 | 1.13M | for (int i = 0; i < nInvfBands; i++) { |
190 | 787k | FIXP_DBL accu; |
191 | 787k | FIXP_DBL bwTmp = mapInvfMode(sbr_invf_mode[i], sbr_invf_mode_prev[i], |
192 | 787k | hLppTrans->pSettings->whFactors); |
193 | | |
194 | 787k | if (bwTmp < hLppTrans->bwVectorOld[i]) { |
195 | 101k | accu = fMultDiv2(FL2FXCONST_DBL(0.75f), bwTmp) + |
196 | 101k | fMultDiv2(FL2FXCONST_DBL(0.25f), hLppTrans->bwVectorOld[i]); |
197 | 685k | } else { |
198 | 685k | accu = fMultDiv2(FL2FXCONST_DBL(0.90625f), bwTmp) + |
199 | 685k | fMultDiv2(FL2FXCONST_DBL(0.09375f), hLppTrans->bwVectorOld[i]); |
200 | 685k | } |
201 | | |
202 | 787k | if (accu<FL2FXCONST_DBL(0.015625f)>> 1) { |
203 | 316k | bwVector[i] = FL2FXCONST_DBL(0.0f); |
204 | 471k | } else { |
205 | 471k | bwVector[i] = fixMin(accu << 1, FL2FXCONST_DBL(0.99609375f)); |
206 | 471k | } |
207 | 787k | } |
208 | 342k | } |
209 | | |
210 | | /* Resulting autocorrelation determinant exponent */ |
211 | | #define ACDET_EXP \ |
212 | | (2 * (DFRACT_BITS + sbrScaleFactor->lb_scale + 10 - ac.det_scale)) |
213 | | #define AC_EXP (-sbrScaleFactor->lb_scale + LPC_SCALE_FACTOR) |
214 | | #define ALPHA_EXP (-sbrScaleFactor->lb_scale + LPC_SCALE_FACTOR + 1) |
215 | | /* Resulting transposed QMF values exponent 16 bit normalized samplebits |
216 | | * assumed. */ |
217 | | #define QMFOUT_EXP ((SAMPLE_BITS - 15) - sbrScaleFactor->lb_scale) |
218 | | |
219 | | static inline void calc_qmfBufferReal(FIXP_DBL **qmfBufferReal, |
220 | | const FIXP_DBL *const lowBandReal, |
221 | | const int startSample, |
222 | | const int stopSample, const UCHAR hiBand, |
223 | | const int dynamicScale, |
224 | 154k | const FIXP_SGL a0r, const FIXP_SGL a1r) { |
225 | 154k | const int dynscale = fixMax(0, dynamicScale - 1) + 1; |
226 | 154k | const int rescale = -fixMin(0, dynamicScale - 1) + 1; |
227 | 154k | const int descale = |
228 | 154k | fixMin(DFRACT_BITS - 1, LPC_SCALE_FACTOR + dynamicScale + rescale); |
229 | | |
230 | 4.06M | for (int i = 0; i < stopSample - startSample; i++) { |
231 | 3.90M | FIXP_DBL accu; |
232 | | |
233 | 3.90M | accu = fMultDiv2(a1r, lowBandReal[i]) + fMultDiv2(a0r, lowBandReal[i + 1]); |
234 | 3.90M | accu = (lowBandReal[i + 2] >> descale) + (accu >> dynscale); |
235 | | |
236 | 3.90M | qmfBufferReal[i + startSample][hiBand] = |
237 | 3.90M | SATURATE_LEFT_SHIFT(accu, rescale, DFRACT_BITS); |
238 | 3.90M | } |
239 | 154k | } |
240 | | |
241 | | /*! |
242 | | * |
243 | | * \brief Perform transposition by patching of subband samples. |
244 | | * This function serves as the main entry point into the module. The function |
245 | | * determines the areas for the patching process (these are the source range as |
246 | | * well as the target range) and implements spectral whitening by means of |
247 | | * inverse filtering. The function autoCorrelation2nd() is an auxiliary function |
248 | | * for calculating the LPC coefficients for the filtering. The actual |
249 | | * calculation of the LPC coefficients and the implementation of the filtering |
250 | | * are done as part of lppTransposer(). |
251 | | * |
252 | | * Note that the filtering is done on all available QMF subsamples, whereas the |
253 | | * patching is only done on those QMF subsamples that will be used in the next |
254 | | * QMF synthesis. The filtering is also implemented before the patching includes |
255 | | * further dependencies on parameters from the SBR data. |
256 | | * |
257 | | */ |
258 | | |
259 | | void lppTransposer( |
260 | | HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */ |
261 | | QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */ |
262 | | FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband |
263 | | samples (source) */ |
264 | | |
265 | | FIXP_DBL *degreeAlias, /*!< Vector for results of aliasing estimation */ |
266 | | FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of |
267 | | subband samples (source) */ |
268 | | const int useLP, const int fPreWhitening, const int v_k_master0, |
269 | | const int timeStep, /*!< Time step of envelope */ |
270 | | const int firstSlotOffs, /*!< Start position in time */ |
271 | | const int lastSlotOffs, /*!< Number of overlap-slots into next frame */ |
272 | | const int nInvfBands, /*!< Number of bands for inverse filtering */ |
273 | | INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */ |
274 | | INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */ |
275 | 283k | ) { |
276 | 283k | INT bwIndex[MAX_NUM_PATCHES]; |
277 | 283k | FIXP_DBL bwVector[MAX_NUM_PATCHES]; /*!< pole moving factors */ |
278 | 283k | FIXP_DBL preWhiteningGains[(64) / 2]; |
279 | 283k | int preWhiteningGains_exp[(64) / 2]; |
280 | | |
281 | 283k | int i; |
282 | 283k | int loBand, start, stop; |
283 | 283k | TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings; |
284 | 283k | PATCH_PARAM *patchParam = pSettings->patchParam; |
285 | 283k | int patch; |
286 | | |
287 | 283k | FIXP_SGL alphar[LPC_ORDER], a0r, a1r; |
288 | 283k | FIXP_SGL alphai[LPC_ORDER], a0i = 0, a1i = 0; |
289 | 283k | FIXP_SGL bw = FL2FXCONST_SGL(0.0f); |
290 | | |
291 | 283k | int autoCorrLength; |
292 | | |
293 | 283k | FIXP_DBL k1, k1_below = 0, k1_below2 = 0; |
294 | | |
295 | 283k | ACORR_COEFS ac; |
296 | 283k | int startSample; |
297 | 283k | int stopSample; |
298 | 283k | int stopSampleClear; |
299 | | |
300 | 283k | int comLowBandScale; |
301 | 283k | int ovLowBandShift; |
302 | 283k | int lowBandShift; |
303 | | /* int ovHighBandShift;*/ |
304 | | |
305 | 283k | alphai[0] = FL2FXCONST_SGL(0.0f); |
306 | 283k | alphai[1] = FL2FXCONST_SGL(0.0f); |
307 | | |
308 | 283k | startSample = firstSlotOffs * timeStep; |
309 | 283k | stopSample = pSettings->nCols + lastSlotOffs * timeStep; |
310 | 283k | FDK_ASSERT((lastSlotOffs * timeStep) <= pSettings->overlap); |
311 | | |
312 | 283k | inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode, |
313 | 283k | sbr_invf_mode_prev, bwVector); |
314 | | |
315 | 283k | stopSampleClear = stopSample; |
316 | | |
317 | 283k | autoCorrLength = pSettings->nCols + pSettings->overlap; |
318 | | |
319 | 283k | if (pSettings->noOfPatches > 0) { |
320 | | /* Set upper subbands to zero: |
321 | | This is required in case that the patches do not cover the complete |
322 | | highband (because the last patch would be too short). Possible |
323 | | optimization: Clearing bands up to usb would be sufficient here. */ |
324 | 283k | int targetStopBand = |
325 | 283k | patchParam[pSettings->noOfPatches - 1].targetStartBand + |
326 | 283k | patchParam[pSettings->noOfPatches - 1].numBandsInPatch; |
327 | | |
328 | 283k | int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL); |
329 | | |
330 | 283k | if (!useLP) { |
331 | 8.37M | for (i = startSample; i < stopSampleClear; i++) { |
332 | 8.13M | FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize); |
333 | 8.13M | FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize); |
334 | 8.13M | } |
335 | 236k | } else { |
336 | 1.21M | for (i = startSample; i < stopSampleClear; i++) { |
337 | 1.16M | FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize); |
338 | 1.16M | } |
339 | 47.0k | } |
340 | 283k | } |
341 | | #if defined __ANDROID__ && !defined __ANDROID_NDK__ |
342 | | else { |
343 | | // Safetynet logging |
344 | | android_errorWriteLog(0x534e4554, "112160868"); |
345 | | } |
346 | | #endif |
347 | | |
348 | | /* init bwIndex for each patch */ |
349 | 283k | FDKmemclear(bwIndex, sizeof(bwIndex)); |
350 | | |
351 | | /* |
352 | | Calc common low band scale factor |
353 | | */ |
354 | 283k | comLowBandScale = |
355 | 283k | fixMin(sbrScaleFactor->ov_lb_scale, sbrScaleFactor->lb_scale); |
356 | | |
357 | 283k | ovLowBandShift = sbrScaleFactor->ov_lb_scale - comLowBandScale; |
358 | 283k | lowBandShift = sbrScaleFactor->lb_scale - comLowBandScale; |
359 | | /* ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/ |
360 | | |
361 | 283k | if (fPreWhitening) { |
362 | 50.6k | sbrDecoder_calculateGainVec( |
363 | 50.6k | qmfBufferReal, qmfBufferImag, |
364 | 50.6k | DFRACT_BITS - 1 - 16 - |
365 | 50.6k | sbrScaleFactor->ov_lb_scale, /* convert scale to exponent */ |
366 | 50.6k | DFRACT_BITS - 1 - 16 - |
367 | 50.6k | sbrScaleFactor->lb_scale, /* convert scale to exponent */ |
368 | 50.6k | pSettings->overlap, preWhiteningGains, preWhiteningGains_exp, |
369 | 50.6k | v_k_master0, startSample, stopSample); |
370 | 50.6k | } |
371 | | |
372 | | /* outer loop over bands to do analysis only once for each band */ |
373 | | |
374 | 283k | if (!useLP) { |
375 | 236k | start = pSettings->lbStartPatching; |
376 | 236k | stop = pSettings->lbStopPatching; |
377 | 236k | } else { |
378 | 47.0k | start = fixMax(1, pSettings->lbStartPatching - 2); |
379 | 47.0k | stop = patchParam[0].targetStartBand; |
380 | 47.0k | } |
381 | | |
382 | 4.22M | for (loBand = start; loBand < stop; loBand++) { |
383 | 3.94M | FIXP_DBL lowBandReal[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER]; |
384 | 3.94M | FIXP_DBL *plowBandReal = lowBandReal; |
385 | 3.94M | FIXP_DBL **pqmfBufferReal = |
386 | 3.94M | qmfBufferReal + firstSlotOffs * timeStep /* + pSettings->overlap */; |
387 | 3.94M | FIXP_DBL lowBandImag[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER]; |
388 | 3.94M | FIXP_DBL *plowBandImag = lowBandImag; |
389 | 3.94M | FIXP_DBL **pqmfBufferImag = |
390 | 3.94M | qmfBufferImag + firstSlotOffs * timeStep /* + pSettings->overlap */; |
391 | 3.94M | int resetLPCCoeffs = 0; |
392 | 3.94M | int dynamicScale = DFRACT_BITS - 1 - LPC_SCALE_FACTOR; |
393 | 3.94M | int acDetScale = 0; /* scaling of autocorrelation determinant */ |
394 | | |
395 | 3.94M | for (i = 0; |
396 | 21.3M | i < LPC_ORDER + firstSlotOffs * timeStep /*+pSettings->overlap*/; |
397 | 17.4M | i++) { |
398 | 17.4M | *plowBandReal++ = hLppTrans->lpcFilterStatesRealLegSBR[i][loBand]; |
399 | 17.4M | if (!useLP) |
400 | 15.4M | *plowBandImag++ = hLppTrans->lpcFilterStatesImagLegSBR[i][loBand]; |
401 | 17.4M | } |
402 | | |
403 | | /* |
404 | | Take old slope length qmf slot source values out of (overlap)qmf buffer |
405 | | */ |
406 | 3.94M | if (!useLP) { |
407 | 3.07M | for (i = 0; |
408 | 113M | i < pSettings->nCols + pSettings->overlap - firstSlotOffs * timeStep; |
409 | 110M | i++) { |
410 | 110M | *plowBandReal++ = (*pqmfBufferReal++)[loBand]; |
411 | 110M | *plowBandImag++ = (*pqmfBufferImag++)[loBand]; |
412 | 110M | } |
413 | 3.07M | } else { |
414 | | /* pSettings->overlap is always even */ |
415 | 866k | FDK_ASSERT((pSettings->overlap & 1) == 0); |
416 | 14.7M | for (i = 0; i < ((pSettings->nCols + pSettings->overlap - |
417 | 14.7M | firstSlotOffs * timeStep) >> |
418 | 14.7M | 1); |
419 | 13.8M | i++) { |
420 | 13.8M | *plowBandReal++ = (*pqmfBufferReal++)[loBand]; |
421 | 13.8M | *plowBandReal++ = (*pqmfBufferReal++)[loBand]; |
422 | 13.8M | } |
423 | 866k | if (pSettings->nCols & 1) { |
424 | 157k | *plowBandReal++ = (*pqmfBufferReal++)[loBand]; |
425 | 157k | } |
426 | 866k | } |
427 | | |
428 | | /* |
429 | | Determine dynamic scaling value. |
430 | | */ |
431 | 3.94M | dynamicScale = |
432 | 3.94M | fixMin(dynamicScale, |
433 | 3.94M | getScalefactor(lowBandReal, LPC_ORDER + pSettings->overlap) + |
434 | 3.94M | ovLowBandShift); |
435 | 3.94M | dynamicScale = |
436 | 3.94M | fixMin(dynamicScale, |
437 | 3.94M | getScalefactor(&lowBandReal[LPC_ORDER + pSettings->overlap], |
438 | 3.94M | pSettings->nCols) + |
439 | 3.94M | lowBandShift); |
440 | 3.94M | if (!useLP) { |
441 | 3.07M | dynamicScale = |
442 | 3.07M | fixMin(dynamicScale, |
443 | 3.07M | getScalefactor(lowBandImag, LPC_ORDER + pSettings->overlap) + |
444 | 3.07M | ovLowBandShift); |
445 | 3.07M | dynamicScale = |
446 | 3.07M | fixMin(dynamicScale, |
447 | 3.07M | getScalefactor(&lowBandImag[LPC_ORDER + pSettings->overlap], |
448 | 3.07M | pSettings->nCols) + |
449 | 3.07M | lowBandShift); |
450 | 3.07M | } |
451 | | |
452 | 3.94M | if (dynamicScale == 0) { |
453 | | /* In this special case the available headroom bits as well as |
454 | | ovLowBandShift and lowBandShift are zero. The spectrum is limited to |
455 | | prevent -1.0, so negative values for dynamicScale can be avoided. */ |
456 | 4.68M | for (i = 0; i < (LPC_ORDER + pSettings->overlap + pSettings->nCols); |
457 | 4.57M | i++) { |
458 | 4.57M | lowBandReal[i] = fixMax(lowBandReal[i], (FIXP_DBL)0x80000001); |
459 | 4.57M | } |
460 | 116k | if (!useLP) { |
461 | 4.36M | for (i = 0; i < (LPC_ORDER + pSettings->overlap + pSettings->nCols); |
462 | 4.25M | i++) { |
463 | 4.25M | lowBandImag[i] = fixMax(lowBandImag[i], (FIXP_DBL)0x80000001); |
464 | 4.25M | } |
465 | 106k | } |
466 | 3.82M | } else { |
467 | 3.82M | dynamicScale = |
468 | 3.82M | fixMax(0, dynamicScale - |
469 | 3.82M | 1); /* one additional bit headroom to prevent -1.0 */ |
470 | 3.82M | } |
471 | | |
472 | | /* |
473 | | Scale temporal QMF buffer. |
474 | | */ |
475 | 3.94M | scaleValues(&lowBandReal[0], LPC_ORDER + pSettings->overlap, |
476 | 3.94M | dynamicScale - ovLowBandShift); |
477 | 3.94M | scaleValues(&lowBandReal[LPC_ORDER + pSettings->overlap], pSettings->nCols, |
478 | 3.94M | dynamicScale - lowBandShift); |
479 | | |
480 | 3.94M | if (!useLP) { |
481 | 3.07M | scaleValues(&lowBandImag[0], LPC_ORDER + pSettings->overlap, |
482 | 3.07M | dynamicScale - ovLowBandShift); |
483 | 3.07M | scaleValues(&lowBandImag[LPC_ORDER + pSettings->overlap], |
484 | 3.07M | pSettings->nCols, dynamicScale - lowBandShift); |
485 | 3.07M | } |
486 | | |
487 | 3.94M | if (!useLP) { |
488 | 3.07M | acDetScale += autoCorr2nd_cplx(&ac, lowBandReal + LPC_ORDER, |
489 | 3.07M | lowBandImag + LPC_ORDER, autoCorrLength); |
490 | 3.07M | } else { |
491 | 866k | acDetScale += |
492 | 866k | autoCorr2nd_real(&ac, lowBandReal + LPC_ORDER, autoCorrLength); |
493 | 866k | } |
494 | | |
495 | | /* Examine dynamic of determinant in autocorrelation. */ |
496 | 3.94M | acDetScale += 2 * (comLowBandScale + dynamicScale); |
497 | 3.94M | acDetScale *= 2; /* two times reflection coefficent scaling */ |
498 | 3.94M | acDetScale += ac.det_scale; /* ac scaling of determinant */ |
499 | | |
500 | | /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */ |
501 | 3.94M | if (acDetScale > 126) { |
502 | 1.30M | resetLPCCoeffs = 1; |
503 | 1.30M | } |
504 | | |
505 | 3.94M | alphar[1] = FL2FXCONST_SGL(0.0f); |
506 | 3.94M | if (!useLP) alphai[1] = FL2FXCONST_SGL(0.0f); |
507 | | |
508 | 3.94M | if (ac.det != FL2FXCONST_DBL(0.0f)) { |
509 | 2.62M | FIXP_DBL tmp, absTmp, absDet; |
510 | | |
511 | 2.62M | absDet = fixp_abs(ac.det); |
512 | | |
513 | 2.62M | if (!useLP) { |
514 | 2.38M | tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) - |
515 | 2.38M | ((fMultDiv2(ac.r01i, ac.r12i) + fMultDiv2(ac.r02r, ac.r11r)) >> |
516 | 2.38M | (LPC_SCALE_FACTOR - 1)); |
517 | 2.38M | } else { |
518 | 245k | tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) - |
519 | 245k | (fMultDiv2(ac.r02r, ac.r11r) >> (LPC_SCALE_FACTOR - 1)); |
520 | 245k | } |
521 | 2.62M | absTmp = fixp_abs(tmp); |
522 | | |
523 | | /* |
524 | | Quick check: is first filter coeff >= 1(4) |
525 | | */ |
526 | 2.62M | { |
527 | 2.62M | INT scale; |
528 | 2.62M | FIXP_DBL result = fDivNorm(absTmp, absDet, &scale); |
529 | 2.62M | scale = scale + ac.det_scale; |
530 | | |
531 | 2.62M | if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) { |
532 | 7.84k | resetLPCCoeffs = 1; |
533 | 2.61M | } else { |
534 | 2.61M | alphar[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale)); |
535 | 2.61M | if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { |
536 | 2.24M | alphar[1] = -alphar[1]; |
537 | 2.24M | } |
538 | 2.61M | } |
539 | 2.62M | } |
540 | | |
541 | 2.62M | if (!useLP) { |
542 | 2.38M | tmp = (fMultDiv2(ac.r01i, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) + |
543 | 2.38M | ((fMultDiv2(ac.r01r, ac.r12i) - |
544 | 2.38M | (FIXP_DBL)fMultDiv2(ac.r02i, ac.r11r)) >> |
545 | 2.38M | (LPC_SCALE_FACTOR - 1)); |
546 | | |
547 | 2.38M | absTmp = fixp_abs(tmp); |
548 | | |
549 | | /* |
550 | | Quick check: is second filter coeff >= 1(4) |
551 | | */ |
552 | 2.38M | { |
553 | 2.38M | INT scale; |
554 | 2.38M | FIXP_DBL result = fDivNorm(absTmp, absDet, &scale); |
555 | 2.38M | scale = scale + ac.det_scale; |
556 | | |
557 | 2.38M | if ((scale > 0) && |
558 | 2.38M | (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >> |
559 | 163k | scale)) { |
560 | 4.16k | resetLPCCoeffs = 1; |
561 | 2.37M | } else { |
562 | 2.37M | alphai[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale)); |
563 | 2.37M | if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { |
564 | 858k | alphai[1] = -alphai[1]; |
565 | 858k | } |
566 | 2.37M | } |
567 | 2.38M | } |
568 | 2.38M | } |
569 | 2.62M | } |
570 | | |
571 | 3.94M | alphar[0] = FL2FXCONST_SGL(0.0f); |
572 | 3.94M | if (!useLP) alphai[0] = FL2FXCONST_SGL(0.0f); |
573 | | |
574 | 3.94M | if (ac.r11r != FL2FXCONST_DBL(0.0f)) { |
575 | | /* ac.r11r is always >=0 */ |
576 | 2.62M | FIXP_DBL tmp, absTmp; |
577 | | |
578 | 2.62M | if (!useLP) { |
579 | 2.38M | tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) + |
580 | 2.38M | (fMultDiv2(alphar[1], ac.r12r) + fMultDiv2(alphai[1], ac.r12i)); |
581 | 2.38M | } else { |
582 | 246k | if (ac.r01r >= FL2FXCONST_DBL(0.0f)) |
583 | 150k | tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) + |
584 | 150k | fMultDiv2(alphar[1], ac.r12r); |
585 | 95.4k | else |
586 | 95.4k | tmp = -((-ac.r01r) >> (LPC_SCALE_FACTOR + 1)) + |
587 | 95.4k | fMultDiv2(alphar[1], ac.r12r); |
588 | 246k | } |
589 | | |
590 | 2.62M | absTmp = fixp_abs(tmp); |
591 | | |
592 | | /* |
593 | | Quick check: is first filter coeff >= 1(4) |
594 | | */ |
595 | | |
596 | 2.62M | if (absTmp >= (ac.r11r >> 1)) { |
597 | 3.75k | resetLPCCoeffs = 1; |
598 | 2.62M | } else { |
599 | 2.62M | INT scale; |
600 | 2.62M | FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); |
601 | 2.62M | alphar[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1)); |
602 | | |
603 | 2.62M | if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) |
604 | 1.45M | alphar[0] = -alphar[0]; |
605 | 2.62M | } |
606 | | |
607 | 2.62M | if (!useLP) { |
608 | 2.38M | tmp = (ac.r01i >> (LPC_SCALE_FACTOR + 1)) + |
609 | 2.38M | (fMultDiv2(alphai[1], ac.r12r) - fMultDiv2(alphar[1], ac.r12i)); |
610 | | |
611 | 2.38M | absTmp = fixp_abs(tmp); |
612 | | |
613 | | /* |
614 | | Quick check: is second filter coeff >= 1(4) |
615 | | */ |
616 | 2.38M | if (absTmp >= (ac.r11r >> 1)) { |
617 | 4.48k | resetLPCCoeffs = 1; |
618 | 2.37M | } else { |
619 | 2.37M | INT scale; |
620 | 2.37M | FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); |
621 | 2.37M | alphai[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1)); |
622 | 2.37M | if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) |
623 | 1.05M | alphai[0] = -alphai[0]; |
624 | 2.37M | } |
625 | 2.38M | } |
626 | 2.62M | } |
627 | | |
628 | 3.94M | if (!useLP) { |
629 | | /* Now check the quadratic criteria */ |
630 | 3.07M | if ((fMultDiv2(alphar[0], alphar[0]) + fMultDiv2(alphai[0], alphai[0])) >= |
631 | 3.07M | FL2FXCONST_DBL(0.5f)) |
632 | 698 | resetLPCCoeffs = 1; |
633 | 3.07M | if ((fMultDiv2(alphar[1], alphar[1]) + fMultDiv2(alphai[1], alphai[1])) >= |
634 | 3.07M | FL2FXCONST_DBL(0.5f)) |
635 | 742 | resetLPCCoeffs = 1; |
636 | 3.07M | } |
637 | | |
638 | 3.94M | if (resetLPCCoeffs) { |
639 | 1.31M | alphar[0] = FL2FXCONST_SGL(0.0f); |
640 | 1.31M | alphar[1] = FL2FXCONST_SGL(0.0f); |
641 | 1.31M | if (!useLP) { |
642 | 698k | alphai[0] = FL2FXCONST_SGL(0.0f); |
643 | 698k | alphai[1] = FL2FXCONST_SGL(0.0f); |
644 | 698k | } |
645 | 1.31M | } |
646 | | |
647 | 3.94M | if (useLP) { |
648 | | /* Aliasing detection */ |
649 | 866k | if (ac.r11r == FL2FXCONST_DBL(0.0f)) { |
650 | 620k | k1 = FL2FXCONST_DBL(0.0f); |
651 | 620k | } else { |
652 | 246k | if (fixp_abs(ac.r01r) >= fixp_abs(ac.r11r)) { |
653 | 5.54k | if (fMultDiv2(ac.r01r, ac.r11r) < FL2FX_DBL(0.0f)) { |
654 | 1.04k | k1 = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_SGL(1.0f)*/; |
655 | 4.50k | } else { |
656 | | /* Since this value is squared later, it must not ever become -1.0f. |
657 | | */ |
658 | 4.50k | k1 = (FIXP_DBL)(MINVAL_DBL + 1) /*FL2FXCONST_SGL(-1.0f)*/; |
659 | 4.50k | } |
660 | 240k | } else { |
661 | 240k | INT scale; |
662 | 240k | FIXP_DBL result = |
663 | 240k | fDivNorm(fixp_abs(ac.r01r), fixp_abs(ac.r11r), &scale); |
664 | 240k | k1 = scaleValueSaturate(result, scale); |
665 | | |
666 | 240k | if (!((ac.r01r < FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))) { |
667 | 146k | k1 = -k1; |
668 | 146k | } |
669 | 240k | } |
670 | 246k | } |
671 | 866k | if ((loBand > 1) && (loBand < v_k_master0)) { |
672 | | /* Check if the gain should be locked */ |
673 | 721k | FIXP_DBL deg = |
674 | 721k | /*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - fPow2(k1_below); |
675 | 721k | degreeAlias[loBand] = FL2FXCONST_DBL(0.0f); |
676 | 721k | if (((loBand & 1) == 0) && (k1 < FL2FXCONST_DBL(0.0f))) { |
677 | 67.1k | if (k1_below < FL2FXCONST_DBL(0.0f)) { /* 2-Ch Aliasing Detection */ |
678 | 32.8k | degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/; |
679 | 32.8k | if (k1_below2 > |
680 | 32.8k | FL2FXCONST_DBL(0.0f)) { /* 3-Ch Aliasing Detection */ |
681 | 8.35k | degreeAlias[loBand - 1] = deg; |
682 | 8.35k | } |
683 | 34.2k | } else if (k1_below2 > |
684 | 34.2k | FL2FXCONST_DBL(0.0f)) { /* 3-Ch Aliasing Detection */ |
685 | 10.2k | degreeAlias[loBand] = deg; |
686 | 10.2k | } |
687 | 67.1k | } |
688 | 721k | if (((loBand & 1) == 1) && (k1 > FL2FXCONST_DBL(0.0f))) { |
689 | 45.2k | if (k1_below > FL2FXCONST_DBL(0.0f)) { /* 2-CH Aliasing Detection */ |
690 | 19.6k | degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/; |
691 | 19.6k | if (k1_below2 < |
692 | 19.6k | FL2FXCONST_DBL(0.0f)) { /* 3-CH Aliasing Detection */ |
693 | 8.82k | degreeAlias[loBand - 1] = deg; |
694 | 8.82k | } |
695 | 25.6k | } else if (k1_below2 < |
696 | 25.6k | FL2FXCONST_DBL(0.0f)) { /* 3-CH Aliasing Detection */ |
697 | 10.1k | degreeAlias[loBand] = deg; |
698 | 10.1k | } |
699 | 45.2k | } |
700 | 721k | } |
701 | | /* remember k1 values of the 2 QMF channels below the current channel */ |
702 | 866k | k1_below2 = k1_below; |
703 | 866k | k1_below = k1; |
704 | 866k | } |
705 | | |
706 | 3.94M | patch = 0; |
707 | | |
708 | 13.6M | while (patch < pSettings->noOfPatches) { /* inner loop over every patch */ |
709 | | |
710 | 9.73M | int hiBand = loBand + patchParam[patch].targetBandOffs; |
711 | | |
712 | 9.73M | if (loBand < patchParam[patch].sourceStartBand || |
713 | 9.73M | loBand >= patchParam[patch].sourceStopBand |
714 | | //|| hiBand >= hLppTrans->pSettings->noChannels |
715 | 9.73M | ) { |
716 | | /* Lowband not in current patch - proceed */ |
717 | 3.45M | patch++; |
718 | 3.45M | continue; |
719 | 3.45M | } |
720 | | |
721 | 6.28M | FDK_ASSERT(hiBand < (64)); |
722 | | |
723 | | /* bwIndex[patch] is already initialized with value from previous band |
724 | | * inside this patch */ |
725 | 7.10M | while (hiBand >= pSettings->bwBorders[bwIndex[patch]] && |
726 | 7.10M | bwIndex[patch] < MAX_NUM_PATCHES - 1) { |
727 | 823k | bwIndex[patch]++; |
728 | 823k | } |
729 | | |
730 | | /* |
731 | | Filter Step 2: add the left slope with the current filter to the buffer |
732 | | pure source values are already in there |
733 | | */ |
734 | 6.28M | bw = FX_DBL2FX_SGL(bwVector[bwIndex[patch]]); |
735 | | |
736 | 6.28M | a0r = FX_DBL2FX_SGL( |
737 | 6.28M | fMult(bw, alphar[0])); /* Apply current bandwidth expansion factor */ |
738 | | |
739 | 6.28M | if (!useLP) a0i = FX_DBL2FX_SGL(fMult(bw, alphai[0])); |
740 | 6.28M | bw = FX_DBL2FX_SGL(fPow2(bw)); |
741 | 6.28M | a1r = FX_DBL2FX_SGL(fMult(bw, alphar[1])); |
742 | 6.28M | if (!useLP) a1i = FX_DBL2FX_SGL(fMult(bw, alphai[1])); |
743 | | |
744 | | /* |
745 | | Filter Step 3: insert the middle part which won't be windowed |
746 | | */ |
747 | 6.28M | if (bw <= FL2FXCONST_SGL(0.0f)) { |
748 | 2.29M | if (!useLP) { |
749 | 1.72M | int descale = |
750 | 1.72M | fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); |
751 | 59.9M | for (i = startSample; i < stopSample; i++) { |
752 | 58.2M | FIXP_DBL accu1, accu2; |
753 | 58.2M | accu1 = lowBandReal[LPC_ORDER + i] >> descale; |
754 | 58.2M | accu2 = lowBandImag[LPC_ORDER + i] >> descale; |
755 | 58.2M | if (fPreWhitening) { |
756 | 28.0M | accu1 = scaleValueSaturate( |
757 | 28.0M | fMultDiv2(accu1, preWhiteningGains[loBand]), |
758 | 28.0M | preWhiteningGains_exp[loBand] + 1); |
759 | 28.0M | accu2 = scaleValueSaturate( |
760 | 28.0M | fMultDiv2(accu2, preWhiteningGains[loBand]), |
761 | 28.0M | preWhiteningGains_exp[loBand] + 1); |
762 | 28.0M | } |
763 | 58.2M | qmfBufferReal[i][hiBand] = accu1; |
764 | 58.2M | qmfBufferImag[i][hiBand] = accu2; |
765 | 58.2M | } |
766 | 1.72M | } else { |
767 | 566k | int descale = |
768 | 566k | fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); |
769 | 17.6M | for (i = startSample; i < stopSample; i++) { |
770 | 17.1M | qmfBufferReal[i][hiBand] = lowBandReal[LPC_ORDER + i] >> descale; |
771 | 17.1M | } |
772 | 566k | } |
773 | 3.98M | } else { /* bw <= 0 */ |
774 | | |
775 | 3.98M | if (!useLP) { |
776 | 3.83M | const int dynscale = fixMax(0, dynamicScale - 2) + 1; |
777 | 3.83M | const int rescale = -fixMin(0, dynamicScale - 2) + 1; |
778 | 3.83M | const int descale = fixMin(DFRACT_BITS - 1, |
779 | 3.83M | LPC_SCALE_FACTOR + dynamicScale + rescale); |
780 | | |
781 | 132M | for (i = startSample; i < stopSample; i++) { |
782 | 128M | FIXP_DBL accu1, accu2; |
783 | | |
784 | 128M | accu1 = ((fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) - |
785 | 128M | fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1])) >> |
786 | 128M | 1) + |
787 | 128M | ((fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) - |
788 | 128M | fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >> |
789 | 128M | 1); |
790 | 128M | accu2 = ((fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) + |
791 | 128M | fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1])) >> |
792 | 128M | 1) + |
793 | 128M | ((fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) + |
794 | 128M | fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >> |
795 | 128M | 1); |
796 | | |
797 | 128M | accu1 = |
798 | 128M | (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 >> dynscale); |
799 | 128M | accu2 = |
800 | 128M | (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 >> dynscale); |
801 | 128M | if (fPreWhitening) { |
802 | 23.6M | qmfBufferReal[i][hiBand] = scaleValueSaturate( |
803 | 23.6M | fMultDiv2(accu1, preWhiteningGains[loBand]), |
804 | 23.6M | preWhiteningGains_exp[loBand] + 1 + rescale); |
805 | 23.6M | qmfBufferImag[i][hiBand] = scaleValueSaturate( |
806 | 23.6M | fMultDiv2(accu2, preWhiteningGains[loBand]), |
807 | 23.6M | preWhiteningGains_exp[loBand] + 1 + rescale); |
808 | 105M | } else { |
809 | 105M | qmfBufferReal[i][hiBand] = |
810 | 105M | SATURATE_LEFT_SHIFT(accu1, rescale, DFRACT_BITS); |
811 | 105M | qmfBufferImag[i][hiBand] = |
812 | 105M | SATURATE_LEFT_SHIFT(accu2, rescale, DFRACT_BITS); |
813 | 105M | } |
814 | 128M | } |
815 | 3.83M | } else { |
816 | 154k | FDK_ASSERT(dynamicScale >= 0); |
817 | 154k | calc_qmfBufferReal( |
818 | 154k | qmfBufferReal, &(lowBandReal[LPC_ORDER + startSample - 2]), |
819 | 154k | startSample, stopSample, hiBand, dynamicScale, a0r, a1r); |
820 | 154k | } |
821 | 3.98M | } /* bw <= 0 */ |
822 | | |
823 | 6.28M | patch++; |
824 | | |
825 | 6.28M | } /* inner loop over patches */ |
826 | | |
827 | | /* |
828 | | * store the unmodified filter coefficients if there is |
829 | | * an overlapping envelope |
830 | | *****************************************************************/ |
831 | | |
832 | 3.94M | } /* outer loop over bands (loBand) */ |
833 | | |
834 | 283k | if (useLP) { |
835 | 47.0k | for (loBand = pSettings->lbStartPatching; |
836 | 667k | loBand < pSettings->lbStopPatching; loBand++) { |
837 | 620k | patch = 0; |
838 | 1.38M | while (patch < pSettings->noOfPatches) { |
839 | 766k | UCHAR hiBand = loBand + patchParam[patch].targetBandOffs; |
840 | | |
841 | 766k | if (loBand < patchParam[patch].sourceStartBand || |
842 | 766k | loBand >= patchParam[patch].sourceStopBand || |
843 | 766k | hiBand >= (64) /* Highband out of range (biterror) */ |
844 | 766k | ) { |
845 | | /* Lowband not in current patch or highband out of range (might be |
846 | | * caused by biterrors)- proceed */ |
847 | 46.1k | patch++; |
848 | 46.1k | continue; |
849 | 46.1k | } |
850 | | |
851 | 720k | if (hiBand != patchParam[patch].targetStartBand) |
852 | 660k | degreeAlias[hiBand] = degreeAlias[loBand]; |
853 | | |
854 | 720k | patch++; |
855 | 720k | } |
856 | 620k | } /* end for loop */ |
857 | 47.0k | } |
858 | | |
859 | 899k | for (i = 0; i < nInvfBands; i++) { |
860 | 615k | hLppTrans->bwVectorOld[i] = bwVector[i]; |
861 | 615k | } |
862 | | |
863 | | /* |
864 | | set high band scale factor |
865 | | */ |
866 | 283k | sbrScaleFactor->hb_scale = comLowBandScale - (LPC_SCALE_FACTOR); |
867 | 283k | } |
868 | | |
869 | | void lppTransposerHBE( |
870 | | HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */ |
871 | | HANDLE_HBE_TRANSPOSER hQmfTransposer, |
872 | | QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */ |
873 | | FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband |
874 | | samples (source) */ |
875 | | FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of |
876 | | subband samples (source) */ |
877 | | const int timeStep, /*!< Time step of envelope */ |
878 | | const int firstSlotOffs, /*!< Start position in time */ |
879 | | const int lastSlotOffs, /*!< Number of overlap-slots into next frame */ |
880 | | const int nInvfBands, /*!< Number of bands for inverse filtering */ |
881 | | INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */ |
882 | | INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */ |
883 | 58.6k | ) { |
884 | 58.6k | INT bwIndex; |
885 | 58.6k | FIXP_DBL bwVector[MAX_NUM_PATCHES_HBE]; /*!< pole moving factors */ |
886 | | |
887 | 58.6k | int i; |
888 | 58.6k | int loBand, start, stop; |
889 | 58.6k | TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings; |
890 | 58.6k | PATCH_PARAM *patchParam = pSettings->patchParam; |
891 | | |
892 | 58.6k | FIXP_SGL alphar[LPC_ORDER], a0r, a1r; |
893 | 58.6k | FIXP_SGL alphai[LPC_ORDER], a0i = 0, a1i = 0; |
894 | 58.6k | FIXP_SGL bw = FL2FXCONST_SGL(0.0f); |
895 | | |
896 | 58.6k | int autoCorrLength; |
897 | | |
898 | 58.6k | ACORR_COEFS ac; |
899 | 58.6k | int startSample; |
900 | 58.6k | int stopSample; |
901 | 58.6k | int stopSampleClear; |
902 | | |
903 | 58.6k | int comBandScale; |
904 | 58.6k | int ovLowBandShift; |
905 | 58.6k | int lowBandShift; |
906 | | /* int ovHighBandShift;*/ |
907 | | |
908 | 58.6k | alphai[0] = FL2FXCONST_SGL(0.0f); |
909 | 58.6k | alphai[1] = FL2FXCONST_SGL(0.0f); |
910 | | |
911 | 58.6k | startSample = firstSlotOffs * timeStep; |
912 | 58.6k | stopSample = pSettings->nCols + lastSlotOffs * timeStep; |
913 | | |
914 | 58.6k | inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode, |
915 | 58.6k | sbr_invf_mode_prev, bwVector); |
916 | | |
917 | 58.6k | stopSampleClear = stopSample; |
918 | | |
919 | 58.6k | autoCorrLength = pSettings->nCols + pSettings->overlap; |
920 | | |
921 | 58.6k | if (pSettings->noOfPatches > 0) { |
922 | | /* Set upper subbands to zero: |
923 | | This is required in case that the patches do not cover the complete |
924 | | highband (because the last patch would be too short). Possible |
925 | | optimization: Clearing bands up to usb would be sufficient here. */ |
926 | 58.6k | int targetStopBand = |
927 | 58.6k | patchParam[pSettings->noOfPatches - 1].targetStartBand + |
928 | 58.6k | patchParam[pSettings->noOfPatches - 1].numBandsInPatch; |
929 | | |
930 | 58.6k | int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL); |
931 | | |
932 | 3.05M | for (i = startSample; i < stopSampleClear; i++) { |
933 | 2.99M | FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize); |
934 | 2.99M | FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize); |
935 | 2.99M | } |
936 | 58.6k | } |
937 | | #if defined __ANDROID__ && !defined __ANDROID_NDK__ |
938 | | else { |
939 | | // Safetynet logging |
940 | | android_errorWriteLog(0x534e4554, "112160868"); |
941 | | } |
942 | | #endif |
943 | | |
944 | | /* |
945 | | Calc common low band scale factor |
946 | | */ |
947 | 58.6k | comBandScale = sbrScaleFactor->hb_scale; |
948 | | |
949 | 58.6k | ovLowBandShift = sbrScaleFactor->hb_scale - comBandScale; |
950 | 58.6k | lowBandShift = sbrScaleFactor->hb_scale - comBandScale; |
951 | | /* ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/ |
952 | | |
953 | | /* outer loop over bands to do analysis only once for each band */ |
954 | | |
955 | 58.6k | start = hQmfTransposer->startBand; |
956 | 58.6k | stop = hQmfTransposer->stopBand; |
957 | | |
958 | 1.94M | for (loBand = start; loBand < stop; loBand++) { |
959 | 1.88M | bwIndex = 0; |
960 | | |
961 | 1.88M | FIXP_DBL lowBandReal[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER]; |
962 | 1.88M | FIXP_DBL lowBandImag[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER]; |
963 | | |
964 | 1.88M | int resetLPCCoeffs = 0; |
965 | 1.88M | int dynamicScale = DFRACT_BITS - 1 - LPC_SCALE_FACTOR; |
966 | 1.88M | int acDetScale = 0; /* scaling of autocorrelation determinant */ |
967 | | |
968 | 5.66M | for (i = 0; i < LPC_ORDER; i++) { |
969 | 3.77M | lowBandReal[i] = hLppTrans->lpcFilterStatesRealHBE[i][loBand]; |
970 | 3.77M | lowBandImag[i] = hLppTrans->lpcFilterStatesImagHBE[i][loBand]; |
971 | 3.77M | } |
972 | | |
973 | 3.76M | for (; i < LPC_ORDER + firstSlotOffs * timeStep; i++) { |
974 | 1.87M | lowBandReal[i] = hLppTrans->lpcFilterStatesRealHBE[i][loBand]; |
975 | 1.87M | lowBandImag[i] = hLppTrans->lpcFilterStatesImagHBE[i][loBand]; |
976 | 1.87M | } |
977 | | |
978 | | /* |
979 | | Take old slope length qmf slot source values out of (overlap)qmf buffer |
980 | | */ |
981 | 1.88M | for (i = firstSlotOffs * timeStep; |
982 | 106M | i < pSettings->nCols + pSettings->overlap; i++) { |
983 | 104M | lowBandReal[i + LPC_ORDER] = qmfBufferReal[i][loBand]; |
984 | 104M | lowBandImag[i + LPC_ORDER] = qmfBufferImag[i][loBand]; |
985 | 104M | } |
986 | | |
987 | | /* store unmodified values to buffer */ |
988 | 22.4M | for (i = 0; i < LPC_ORDER + pSettings->overlap; i++) { |
989 | 20.5M | hLppTrans->lpcFilterStatesRealHBE[i][loBand] = |
990 | 20.5M | qmfBufferReal[pSettings->nCols - LPC_ORDER + i][loBand]; |
991 | 20.5M | hLppTrans->lpcFilterStatesImagHBE[i][loBand] = |
992 | 20.5M | qmfBufferImag[pSettings->nCols - LPC_ORDER + i][loBand]; |
993 | 20.5M | } |
994 | | |
995 | | /* |
996 | | Determine dynamic scaling value. |
997 | | */ |
998 | 1.88M | dynamicScale = |
999 | 1.88M | fixMin(dynamicScale, |
1000 | 1.88M | getScalefactor(lowBandReal, LPC_ORDER + pSettings->overlap) + |
1001 | 1.88M | ovLowBandShift); |
1002 | 1.88M | dynamicScale = |
1003 | 1.88M | fixMin(dynamicScale, |
1004 | 1.88M | getScalefactor(&lowBandReal[LPC_ORDER + pSettings->overlap], |
1005 | 1.88M | pSettings->nCols) + |
1006 | 1.88M | lowBandShift); |
1007 | 1.88M | dynamicScale = |
1008 | 1.88M | fixMin(dynamicScale, |
1009 | 1.88M | getScalefactor(lowBandImag, LPC_ORDER + pSettings->overlap) + |
1010 | 1.88M | ovLowBandShift); |
1011 | 1.88M | dynamicScale = |
1012 | 1.88M | fixMin(dynamicScale, |
1013 | 1.88M | getScalefactor(&lowBandImag[LPC_ORDER + pSettings->overlap], |
1014 | 1.88M | pSettings->nCols) + |
1015 | 1.88M | lowBandShift); |
1016 | | |
1017 | 1.88M | dynamicScale = |
1018 | 1.88M | dynamicScale - 1; /* one additional bit headroom to prevent -1.0 */ |
1019 | | |
1020 | | /* |
1021 | | Scale temporal QMF buffer. |
1022 | | */ |
1023 | 1.88M | scaleValues(&lowBandReal[0], LPC_ORDER + pSettings->overlap, |
1024 | 1.88M | dynamicScale - ovLowBandShift); |
1025 | 1.88M | scaleValues(&lowBandReal[LPC_ORDER + pSettings->overlap], pSettings->nCols, |
1026 | 1.88M | dynamicScale - lowBandShift); |
1027 | 1.88M | scaleValues(&lowBandImag[0], LPC_ORDER + pSettings->overlap, |
1028 | 1.88M | dynamicScale - ovLowBandShift); |
1029 | 1.88M | scaleValues(&lowBandImag[LPC_ORDER + pSettings->overlap], pSettings->nCols, |
1030 | 1.88M | dynamicScale - lowBandShift); |
1031 | | |
1032 | 1.88M | acDetScale += autoCorr2nd_cplx(&ac, lowBandReal + LPC_ORDER, |
1033 | 1.88M | lowBandImag + LPC_ORDER, autoCorrLength); |
1034 | | |
1035 | | /* Examine dynamic of determinant in autocorrelation. */ |
1036 | 1.88M | acDetScale += 2 * (comBandScale + dynamicScale); |
1037 | 1.88M | acDetScale *= 2; /* two times reflection coefficent scaling */ |
1038 | 1.88M | acDetScale += ac.det_scale; /* ac scaling of determinant */ |
1039 | | |
1040 | | /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */ |
1041 | 1.88M | if (acDetScale > 126) { |
1042 | 863k | resetLPCCoeffs = 1; |
1043 | 863k | } |
1044 | | |
1045 | 1.88M | alphar[1] = FL2FXCONST_SGL(0.0f); |
1046 | 1.88M | alphai[1] = FL2FXCONST_SGL(0.0f); |
1047 | | |
1048 | 1.88M | if (ac.det != FL2FXCONST_DBL(0.0f)) { |
1049 | 1.02M | FIXP_DBL tmp, absTmp, absDet; |
1050 | | |
1051 | 1.02M | absDet = fixp_abs(ac.det); |
1052 | | |
1053 | 1.02M | tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) - |
1054 | 1.02M | ((fMultDiv2(ac.r01i, ac.r12i) + fMultDiv2(ac.r02r, ac.r11r)) >> |
1055 | 1.02M | (LPC_SCALE_FACTOR - 1)); |
1056 | 1.02M | absTmp = fixp_abs(tmp); |
1057 | | |
1058 | | /* |
1059 | | Quick check: is first filter coeff >= 1(4) |
1060 | | */ |
1061 | 1.02M | { |
1062 | 1.02M | INT scale; |
1063 | 1.02M | FIXP_DBL result = fDivNorm(absTmp, absDet, &scale); |
1064 | 1.02M | scale = scale + ac.det_scale; |
1065 | | |
1066 | 1.02M | if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) { |
1067 | 27.3k | resetLPCCoeffs = 1; |
1068 | 995k | } else { |
1069 | 995k | alphar[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale)); |
1070 | 995k | if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { |
1071 | 647k | alphar[1] = -alphar[1]; |
1072 | 647k | } |
1073 | 995k | } |
1074 | 1.02M | } |
1075 | | |
1076 | 1.02M | tmp = (fMultDiv2(ac.r01i, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) + |
1077 | 1.02M | ((fMultDiv2(ac.r01r, ac.r12i) - |
1078 | 1.02M | (FIXP_DBL)fMultDiv2(ac.r02i, ac.r11r)) >> |
1079 | 1.02M | (LPC_SCALE_FACTOR - 1)); |
1080 | | |
1081 | 1.02M | absTmp = fixp_abs(tmp); |
1082 | | |
1083 | | /* |
1084 | | Quick check: is second filter coeff >= 1(4) |
1085 | | */ |
1086 | 1.02M | { |
1087 | 1.02M | INT scale; |
1088 | 1.02M | FIXP_DBL result = fDivNorm(absTmp, absDet, &scale); |
1089 | 1.02M | scale = scale + ac.det_scale; |
1090 | | |
1091 | 1.02M | if ((scale > 0) && |
1092 | 1.02M | (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >> scale)) { |
1093 | 25.1k | resetLPCCoeffs = 1; |
1094 | 997k | } else { |
1095 | 997k | alphai[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale)); |
1096 | 997k | if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { |
1097 | 449k | alphai[1] = -alphai[1]; |
1098 | 449k | } |
1099 | 997k | } |
1100 | 1.02M | } |
1101 | 1.02M | } |
1102 | | |
1103 | 1.88M | alphar[0] = FL2FXCONST_SGL(0.0f); |
1104 | 1.88M | alphai[0] = FL2FXCONST_SGL(0.0f); |
1105 | | |
1106 | 1.88M | if (ac.r11r != FL2FXCONST_DBL(0.0f)) { |
1107 | | /* ac.r11r is always >=0 */ |
1108 | 1.02M | FIXP_DBL tmp, absTmp; |
1109 | | |
1110 | 1.02M | tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) + |
1111 | 1.02M | (fMultDiv2(alphar[1], ac.r12r) + fMultDiv2(alphai[1], ac.r12i)); |
1112 | | |
1113 | 1.02M | absTmp = fixp_abs(tmp); |
1114 | | |
1115 | | /* |
1116 | | Quick check: is first filter coeff >= 1(4) |
1117 | | */ |
1118 | | |
1119 | 1.02M | if (absTmp >= (ac.r11r >> 1)) { |
1120 | 1.75k | resetLPCCoeffs = 1; |
1121 | 1.02M | } else { |
1122 | 1.02M | INT scale; |
1123 | 1.02M | FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); |
1124 | 1.02M | alphar[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1)); |
1125 | | |
1126 | 1.02M | if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) |
1127 | 639k | alphar[0] = -alphar[0]; |
1128 | 1.02M | } |
1129 | | |
1130 | 1.02M | tmp = (ac.r01i >> (LPC_SCALE_FACTOR + 1)) + |
1131 | 1.02M | (fMultDiv2(alphai[1], ac.r12r) - fMultDiv2(alphar[1], ac.r12i)); |
1132 | | |
1133 | 1.02M | absTmp = fixp_abs(tmp); |
1134 | | |
1135 | | /* |
1136 | | Quick check: is second filter coeff >= 1(4) |
1137 | | */ |
1138 | 1.02M | if (absTmp >= (ac.r11r >> 1)) { |
1139 | 2.46k | resetLPCCoeffs = 1; |
1140 | 1.02M | } else { |
1141 | 1.02M | INT scale; |
1142 | 1.02M | FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); |
1143 | 1.02M | alphai[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1)); |
1144 | 1.02M | if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) { |
1145 | 505k | alphai[0] = -alphai[0]; |
1146 | 505k | } |
1147 | 1.02M | } |
1148 | 1.02M | } |
1149 | | |
1150 | | /* Now check the quadratic criteria */ |
1151 | 1.88M | if ((fMultDiv2(alphar[0], alphar[0]) + fMultDiv2(alphai[0], alphai[0])) >= |
1152 | 1.88M | FL2FXCONST_DBL(0.5f)) { |
1153 | 1.41k | resetLPCCoeffs = 1; |
1154 | 1.41k | } |
1155 | 1.88M | if ((fMultDiv2(alphar[1], alphar[1]) + fMultDiv2(alphai[1], alphai[1])) >= |
1156 | 1.88M | FL2FXCONST_DBL(0.5f)) { |
1157 | 4.82k | resetLPCCoeffs = 1; |
1158 | 4.82k | } |
1159 | | |
1160 | 1.88M | if (resetLPCCoeffs) { |
1161 | 909k | alphar[0] = FL2FXCONST_SGL(0.0f); |
1162 | 909k | alphar[1] = FL2FXCONST_SGL(0.0f); |
1163 | 909k | alphai[0] = FL2FXCONST_SGL(0.0f); |
1164 | 909k | alphai[1] = FL2FXCONST_SGL(0.0f); |
1165 | 909k | } |
1166 | | |
1167 | 5.51M | while (bwIndex < MAX_NUM_PATCHES - 1 && |
1168 | 5.51M | loBand >= pSettings->bwBorders[bwIndex]) { |
1169 | 3.62M | bwIndex++; |
1170 | 3.62M | } |
1171 | | |
1172 | | /* |
1173 | | Filter Step 2: add the left slope with the current filter to the buffer |
1174 | | pure source values are already in there |
1175 | | */ |
1176 | 1.88M | bw = FX_DBL2FX_SGL(bwVector[bwIndex]); |
1177 | | |
1178 | 1.88M | a0r = FX_DBL2FX_SGL( |
1179 | 1.88M | fMult(bw, alphar[0])); /* Apply current bandwidth expansion factor */ |
1180 | 1.88M | a0i = FX_DBL2FX_SGL(fMult(bw, alphai[0])); |
1181 | 1.88M | bw = FX_DBL2FX_SGL(fPow2(bw)); |
1182 | 1.88M | a1r = FX_DBL2FX_SGL(fMult(bw, alphar[1])); |
1183 | 1.88M | a1i = FX_DBL2FX_SGL(fMult(bw, alphai[1])); |
1184 | | |
1185 | | /* |
1186 | | Filter Step 3: insert the middle part which won't be windowed |
1187 | | */ |
1188 | 1.88M | if (bw <= FL2FXCONST_SGL(0.0f)) { |
1189 | 1.31M | int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); |
1190 | 57.4M | for (i = startSample; i < stopSample; i++) { |
1191 | 56.1M | qmfBufferReal[i][loBand] = lowBandReal[LPC_ORDER + i] >> descale; |
1192 | 56.1M | qmfBufferImag[i][loBand] = lowBandImag[LPC_ORDER + i] >> descale; |
1193 | 56.1M | } |
1194 | 1.31M | } else { /* bw <= 0 */ |
1195 | | |
1196 | 577k | int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); |
1197 | 577k | dynamicScale += |
1198 | 577k | 1; /* prevent negativ scale factor due to 'one additional bit |
1199 | | headroom' */ |
1200 | | |
1201 | 32.8M | for (i = startSample; i < stopSample; i++) { |
1202 | 32.2M | FIXP_DBL accu1, accu2; |
1203 | | |
1204 | 32.2M | accu1 = (fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) - |
1205 | 32.2M | fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1]) + |
1206 | 32.2M | fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) - |
1207 | 32.2M | fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >> |
1208 | 32.2M | dynamicScale; |
1209 | 32.2M | accu2 = (fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) + |
1210 | 32.2M | fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1]) + |
1211 | 32.2M | fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) + |
1212 | 32.2M | fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >> |
1213 | 32.2M | dynamicScale; |
1214 | | |
1215 | 32.2M | qmfBufferReal[i][loBand] = |
1216 | 32.2M | (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << (1 + 1)); |
1217 | 32.2M | qmfBufferImag[i][loBand] = |
1218 | 32.2M | (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << (1 + 1)); |
1219 | 32.2M | } |
1220 | 577k | } /* bw <= 0 */ |
1221 | | |
1222 | | /* |
1223 | | * store the unmodified filter coefficients if there is |
1224 | | * an overlapping envelope |
1225 | | *****************************************************************/ |
1226 | | |
1227 | 1.88M | } /* outer loop over bands (loBand) */ |
1228 | | |
1229 | 230k | for (i = 0; i < nInvfBands; i++) { |
1230 | 171k | hLppTrans->bwVectorOld[i] = bwVector[i]; |
1231 | 171k | } |
1232 | | |
1233 | | /* |
1234 | | set high band scale factor |
1235 | | */ |
1236 | 58.6k | sbrScaleFactor->hb_scale = comBandScale - (LPC_SCALE_FACTOR); |
1237 | 58.6k | } |
1238 | | |
1239 | | /*! |
1240 | | * |
1241 | | * \brief Initialize one low power transposer instance |
1242 | | * |
1243 | | * |
1244 | | */ |
1245 | | SBR_ERROR |
1246 | | createLppTransposer( |
1247 | | HANDLE_SBR_LPP_TRANS hs, /*!< Handle of low power transposer */ |
1248 | | TRANSPOSER_SETTINGS *pSettings, /*!< Pointer to settings */ |
1249 | | const int highBandStartSb, /*!< ? */ |
1250 | | UCHAR *v_k_master, /*!< Master table */ |
1251 | | const int numMaster, /*!< Valid entries in master table */ |
1252 | | const int usb, /*!< Highband area stop subband */ |
1253 | | const int timeSlots, /*!< Number of time slots */ |
1254 | | const int nCols, /*!< Number of colums (codec qmf bank) */ |
1255 | | UCHAR *noiseBandTable, /*!< Mapping of SBR noise bands to QMF bands */ |
1256 | | const int noNoiseBands, /*!< Number of noise bands */ |
1257 | | UINT fs, /*!< Sample Frequency */ |
1258 | | const int chan, /*!< Channel number */ |
1259 | 162k | const int overlap) { |
1260 | | /* FB inverse filtering settings */ |
1261 | 162k | hs->pSettings = pSettings; |
1262 | | |
1263 | 162k | pSettings->nCols = nCols; |
1264 | 162k | pSettings->overlap = overlap; |
1265 | | |
1266 | 162k | switch (timeSlots) { |
1267 | 65.7k | case 15: |
1268 | 162k | case 16: |
1269 | 162k | break; |
1270 | | |
1271 | 0 | default: |
1272 | 0 | return SBRDEC_UNSUPPORTED_CONFIG; /* Unimplemented */ |
1273 | 162k | } |
1274 | | |
1275 | 162k | if (chan == 0) { |
1276 | | /* Init common data only once */ |
1277 | 105k | hs->pSettings->nCols = nCols; |
1278 | | |
1279 | 105k | return resetLppTransposer(hs, highBandStartSb, v_k_master, numMaster, |
1280 | 105k | noiseBandTable, noNoiseBands, usb, fs); |
1281 | 105k | } |
1282 | 57.5k | return SBRDEC_OK; |
1283 | 162k | } |
1284 | | |
1285 | | static int findClosestEntry(UCHAR goalSb, UCHAR *v_k_master, UCHAR numMaster, |
1286 | 871k | UCHAR direction) { |
1287 | 871k | int index; |
1288 | | |
1289 | 871k | if (goalSb <= v_k_master[0]) return v_k_master[0]; |
1290 | | |
1291 | 842k | if (goalSb >= v_k_master[numMaster]) return v_k_master[numMaster]; |
1292 | | |
1293 | 463k | if (direction) { |
1294 | 20.2k | index = 0; |
1295 | 258k | while (v_k_master[index] < goalSb) { |
1296 | 238k | index++; |
1297 | 238k | } |
1298 | 442k | } else { |
1299 | 442k | index = numMaster; |
1300 | 2.37M | while (v_k_master[index] > goalSb) { |
1301 | 1.93M | index--; |
1302 | 1.93M | } |
1303 | 442k | } |
1304 | | |
1305 | 463k | return v_k_master[index]; |
1306 | 842k | } |
1307 | | |
1308 | | /*! |
1309 | | * |
1310 | | * \brief Reset memory for one lpp transposer instance |
1311 | | * |
1312 | | * \return SBRDEC_OK on success, SBRDEC_UNSUPPORTED_CONFIG on error |
1313 | | */ |
1314 | | SBR_ERROR |
1315 | | resetLppTransposer( |
1316 | | HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */ |
1317 | | UCHAR highBandStartSb, /*!< High band area: start subband */ |
1318 | | UCHAR *v_k_master, /*!< Master table */ |
1319 | | UCHAR numMaster, /*!< Valid entries in master table */ |
1320 | | UCHAR *noiseBandTable, /*!< Mapping of SBR noise bands to QMF bands */ |
1321 | | UCHAR noNoiseBands, /*!< Number of noise bands */ |
1322 | | UCHAR usb, /*!< High band area: stop subband */ |
1323 | | UINT fs /*!< SBR output sampling frequency */ |
1324 | 424k | ) { |
1325 | 424k | TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings; |
1326 | 424k | PATCH_PARAM *patchParam = pSettings->patchParam; |
1327 | | |
1328 | 424k | int i, patch; |
1329 | 424k | int targetStopBand; |
1330 | 424k | int sourceStartBand; |
1331 | 424k | int patchDistance; |
1332 | 424k | int numBandsInPatch; |
1333 | | |
1334 | 424k | int lsb = v_k_master[0]; /* Start subband expressed in "non-critical" sampling |
1335 | | terms*/ |
1336 | 424k | int xoverOffset = highBandStartSb - |
1337 | 424k | lsb; /* Calculate distance in QMF bands between k0 and kx */ |
1338 | 424k | int startFreqHz; |
1339 | | |
1340 | 424k | int desiredBorder; |
1341 | | |
1342 | 424k | usb = fixMin(usb, v_k_master[numMaster]); /* Avoid endless loops (compare with |
1343 | | float code). */ |
1344 | | |
1345 | | /* |
1346 | | * Plausibility check |
1347 | | */ |
1348 | | |
1349 | 424k | if (pSettings->nCols == 64) { |
1350 | 29.8k | if (lsb < 4) { |
1351 | | /* 4:1 SBR Requirement k0 >= 4 missed! */ |
1352 | 89 | return SBRDEC_UNSUPPORTED_CONFIG; |
1353 | 89 | } |
1354 | 394k | } else if (lsb - SHIFT_START_SB < 4) { |
1355 | 106 | return SBRDEC_UNSUPPORTED_CONFIG; |
1356 | 106 | } |
1357 | | |
1358 | | /* |
1359 | | * Initialize the patching parameter |
1360 | | */ |
1361 | | /* ISO/IEC 14496-3 (Figure 4.48): goalSb = round( 2.048e6 / fs ) */ |
1362 | 424k | desiredBorder = (((2048000 * 2) / fs) + 1) >> 1; |
1363 | | |
1364 | 424k | desiredBorder = findClosestEntry(desiredBorder, v_k_master, numMaster, |
1365 | 424k | 1); /* Adapt region to master-table */ |
1366 | | |
1367 | | /* First patch */ |
1368 | 424k | sourceStartBand = SHIFT_START_SB + xoverOffset; |
1369 | 424k | targetStopBand = lsb + xoverOffset; /* upperBand */ |
1370 | | |
1371 | | /* Even (odd) numbered channel must be patched to even (odd) numbered channel |
1372 | | */ |
1373 | 424k | patch = 0; |
1374 | 1.21M | while (targetStopBand < usb) { |
1375 | | /* Too many patches? |
1376 | | Allow MAX_NUM_PATCHES+1 patches here. |
1377 | | we need to check later again, since patch might be the highest patch |
1378 | | AND contain less than 3 bands => actual number of patches will be reduced |
1379 | | by 1. |
1380 | | */ |
1381 | 791k | if (patch > MAX_NUM_PATCHES) { |
1382 | 256 | return SBRDEC_UNSUPPORTED_CONFIG; |
1383 | 256 | } |
1384 | | |
1385 | 791k | patchParam[patch].guardStartBand = targetStopBand; |
1386 | 791k | patchParam[patch].targetStartBand = targetStopBand; |
1387 | | |
1388 | 791k | numBandsInPatch = |
1389 | 791k | desiredBorder - targetStopBand; /* Get the desired range of the patch */ |
1390 | | |
1391 | 791k | if (numBandsInPatch >= lsb - sourceStartBand) { |
1392 | | /* Desired number bands are not available -> patch whole source range */ |
1393 | 446k | patchDistance = |
1394 | 446k | targetStopBand - sourceStartBand; /* Get the targetOffset */ |
1395 | 446k | patchDistance = |
1396 | 446k | patchDistance & ~1; /* Rounding off odd numbers and make all even */ |
1397 | 446k | numBandsInPatch = |
1398 | 446k | lsb - (targetStopBand - |
1399 | 446k | patchDistance); /* Update number of bands to be patched */ |
1400 | 446k | numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch, |
1401 | 446k | v_k_master, numMaster, 0) - |
1402 | 446k | targetStopBand; /* Adapt region to master-table */ |
1403 | 446k | } |
1404 | | |
1405 | 791k | if (pSettings->nCols == 64) { |
1406 | 81.0k | if (numBandsInPatch == 0 && sourceStartBand == SHIFT_START_SB) { |
1407 | 324 | return SBRDEC_UNSUPPORTED_CONFIG; |
1408 | 324 | } |
1409 | 81.0k | } |
1410 | | |
1411 | | /* Desired number bands are available -> get the minimal even patching |
1412 | | * distance */ |
1413 | 791k | patchDistance = |
1414 | 791k | numBandsInPatch + targetStopBand - lsb; /* Get minimal distance */ |
1415 | 791k | patchDistance = (patchDistance + 1) & |
1416 | 791k | ~1; /* Rounding up odd numbers and make all even */ |
1417 | | |
1418 | 791k | if (numBandsInPatch > 0) { |
1419 | 760k | patchParam[patch].sourceStartBand = targetStopBand - patchDistance; |
1420 | 760k | patchParam[patch].targetBandOffs = patchDistance; |
1421 | 760k | patchParam[patch].numBandsInPatch = numBandsInPatch; |
1422 | 760k | patchParam[patch].sourceStopBand = |
1423 | 760k | patchParam[patch].sourceStartBand + numBandsInPatch; |
1424 | | |
1425 | 760k | targetStopBand += patchParam[patch].numBandsInPatch; |
1426 | 760k | patch++; |
1427 | 760k | } |
1428 | | |
1429 | | /* All patches but first */ |
1430 | 791k | sourceStartBand = SHIFT_START_SB; |
1431 | | |
1432 | | /* Check if we are close to desiredBorder */ |
1433 | 791k | if (desiredBorder - targetStopBand < 3) /* MPEG doc */ |
1434 | 386k | { |
1435 | 386k | desiredBorder = usb; |
1436 | 386k | } |
1437 | 791k | } |
1438 | | |
1439 | 423k | patch--; |
1440 | | |
1441 | | /* If highest patch contains less than three subband: skip it */ |
1442 | 423k | if ((patch > 0) && (patchParam[patch].numBandsInPatch < 3)) { |
1443 | 37.1k | patch--; |
1444 | 37.1k | targetStopBand = |
1445 | 37.1k | patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch; |
1446 | 37.1k | } |
1447 | | |
1448 | | /* now check if we don't have one too many */ |
1449 | 423k | if (patch >= MAX_NUM_PATCHES) { |
1450 | 743 | return SBRDEC_UNSUPPORTED_CONFIG; |
1451 | 743 | } |
1452 | | |
1453 | 423k | pSettings->noOfPatches = patch + 1; |
1454 | | |
1455 | | /* Check lowest and highest source subband */ |
1456 | 423k | pSettings->lbStartPatching = targetStopBand; |
1457 | 423k | pSettings->lbStopPatching = 0; |
1458 | 1.13M | for (patch = 0; patch < pSettings->noOfPatches; patch++) { |
1459 | 714k | pSettings->lbStartPatching = |
1460 | 714k | fixMin(pSettings->lbStartPatching, patchParam[patch].sourceStartBand); |
1461 | 714k | pSettings->lbStopPatching = |
1462 | 714k | fixMax(pSettings->lbStopPatching, patchParam[patch].sourceStopBand); |
1463 | 714k | } |
1464 | | |
1465 | 1.41M | for (i = 0; i < noNoiseBands; i++) { |
1466 | 991k | pSettings->bwBorders[i] = noiseBandTable[i + 1]; |
1467 | 991k | } |
1468 | 3.66M | for (; i < MAX_NUM_NOISE_VALUES; i++) { |
1469 | 3.24M | pSettings->bwBorders[i] = 255; |
1470 | 3.24M | } |
1471 | | |
1472 | | /* |
1473 | | * Choose whitening factors |
1474 | | */ |
1475 | | |
1476 | 423k | startFreqHz = |
1477 | 423k | ((lsb + xoverOffset) * fs) >> 7; /* Shift does a division by 2*(64) */ |
1478 | | |
1479 | 1.26M | for (i = 1; i < NUM_WHFACTOR_TABLE_ENTRIES; i++) { |
1480 | 1.19M | if (startFreqHz < FDK_sbrDecoder_sbr_whFactorsIndex[i]) break; |
1481 | 1.19M | } |
1482 | 423k | i--; |
1483 | | |
1484 | 423k | pSettings->whFactors.off = FDK_sbrDecoder_sbr_whFactorsTable[i][0]; |
1485 | 423k | pSettings->whFactors.transitionLevel = |
1486 | 423k | FDK_sbrDecoder_sbr_whFactorsTable[i][1]; |
1487 | 423k | pSettings->whFactors.lowLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][2]; |
1488 | 423k | pSettings->whFactors.midLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][3]; |
1489 | 423k | pSettings->whFactors.highLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][4]; |
1490 | | |
1491 | 423k | return SBRDEC_OK; |
1492 | 423k | } |