/src/aac/libSBRdec/src/env_dec.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 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten |
5 | | Forschung e.V. All rights reserved. |
6 | | |
7 | | 1. INTRODUCTION |
8 | | The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software |
9 | | that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding |
10 | | scheme for digital audio. This FDK AAC Codec software is intended to be used on |
11 | | a wide variety of Android devices. |
12 | | |
13 | | AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient |
14 | | general perceptual audio codecs. AAC-ELD is considered the best-performing |
15 | | full-bandwidth communications codec by independent studies and is widely |
16 | | deployed. AAC has been standardized by ISO and IEC as part of the MPEG |
17 | | specifications. |
18 | | |
19 | | Patent licenses for necessary patent claims for the FDK AAC Codec (including |
20 | | those of Fraunhofer) may be obtained through Via Licensing |
21 | | (www.vialicensing.com) or through the respective patent owners individually for |
22 | | the purpose of encoding or decoding bit streams in products that are compliant |
23 | | with the ISO/IEC MPEG audio standards. Please note that most manufacturers of |
24 | | Android devices already license these patent claims through Via Licensing or |
25 | | directly from the patent owners, and therefore FDK AAC Codec software may |
26 | | already be covered under those patent licenses when it is used for those |
27 | | licensed purposes only. |
28 | | |
29 | | Commercially-licensed AAC software libraries, including floating-point versions |
30 | | with enhanced sound quality, are also available from Fraunhofer. Users are |
31 | | encouraged to check the Fraunhofer website for additional applications |
32 | | information and documentation. |
33 | | |
34 | | 2. COPYRIGHT LICENSE |
35 | | |
36 | | Redistribution and use in source and binary forms, with or without modification, |
37 | | are permitted without payment of copyright license fees provided that you |
38 | | satisfy the following conditions: |
39 | | |
40 | | You must retain the complete text of this software license in redistributions of |
41 | | the FDK AAC Codec or your modifications thereto in source code form. |
42 | | |
43 | | You must retain the complete text of this software license in the documentation |
44 | | and/or other materials provided with redistributions of the FDK AAC Codec or |
45 | | your modifications thereto in binary form. You must make available free of |
46 | | charge copies of the complete source code of the FDK AAC Codec and your |
47 | | modifications thereto to recipients of copies in binary form. |
48 | | |
49 | | The name of Fraunhofer may not be used to endorse or promote products derived |
50 | | from this library without prior written permission. |
51 | | |
52 | | You may not charge copyright license fees for anyone to use, copy or distribute |
53 | | the FDK AAC Codec software or your modifications thereto. |
54 | | |
55 | | Your modified versions of the FDK AAC Codec must carry prominent notices stating |
56 | | that you changed the software and the date of any change. For modified versions |
57 | | of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" |
58 | | must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK |
59 | | AAC Codec Library for Android." |
60 | | |
61 | | 3. NO PATENT LICENSE |
62 | | |
63 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without |
64 | | limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. |
65 | | Fraunhofer provides no warranty of patent non-infringement with respect to this |
66 | | software. |
67 | | |
68 | | You may use this FDK AAC Codec software or modifications thereto only for |
69 | | purposes that are authorized by appropriate patent licenses. |
70 | | |
71 | | 4. DISCLAIMER |
72 | | |
73 | | This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright |
74 | | holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, |
75 | | including but not limited to the implied warranties of merchantability and |
76 | | fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
77 | | CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, |
78 | | or consequential damages, including but not limited to procurement of substitute |
79 | | goods or services; loss of use, data, or profits, or business interruption, |
80 | | however caused and on any theory of liability, whether in contract, strict |
81 | | liability, or tort (including negligence), arising in any way out of the use of |
82 | | this software, even if advised of the possibility of such damage. |
83 | | |
84 | | 5. CONTACT INFORMATION |
85 | | |
86 | | Fraunhofer Institute for Integrated Circuits IIS |
87 | | Attention: Audio and Multimedia Departments - FDK AAC LL |
88 | | Am Wolfsmantel 33 |
89 | | 91058 Erlangen, Germany |
90 | | |
91 | | www.iis.fraunhofer.de/amm |
92 | | amm-info@iis.fraunhofer.de |
93 | | ----------------------------------------------------------------------------- */ |
94 | | |
95 | | /**************************** SBR decoder library ****************************** |
96 | | |
97 | | Author(s): |
98 | | |
99 | | Description: |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | /*! |
104 | | \file |
105 | | \brief envelope decoding |
106 | | This module provides envelope decoding and error concealment algorithms. The |
107 | | main entry point is decodeSbrData(). |
108 | | |
109 | | \sa decodeSbrData(),\ref documentationOverview |
110 | | */ |
111 | | |
112 | | #include "env_dec.h" |
113 | | |
114 | | #include "env_extr.h" |
115 | | #include "transcendent.h" |
116 | | |
117 | | #include "genericStds.h" |
118 | | |
119 | | static void decodeEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData, |
120 | | HANDLE_SBR_FRAME_DATA h_sbr_data, |
121 | | HANDLE_SBR_PREV_FRAME_DATA h_prev_data, |
122 | | HANDLE_SBR_PREV_FRAME_DATA h_prev_data_otherChannel); |
123 | | static void sbr_envelope_unmapping(HANDLE_SBR_HEADER_DATA hHeaderData, |
124 | | HANDLE_SBR_FRAME_DATA h_data_left, |
125 | | HANDLE_SBR_FRAME_DATA h_data_right); |
126 | | static void requantizeEnvelopeData(HANDLE_SBR_FRAME_DATA h_sbr_data, |
127 | | int ampResolution); |
128 | | static void deltaToLinearPcmEnvelopeDecoding( |
129 | | HANDLE_SBR_HEADER_DATA hHeaderData, HANDLE_SBR_FRAME_DATA h_sbr_data, |
130 | | HANDLE_SBR_PREV_FRAME_DATA h_prev_data); |
131 | | static void decodeNoiseFloorlevels(HANDLE_SBR_HEADER_DATA hHeaderData, |
132 | | HANDLE_SBR_FRAME_DATA h_sbr_data, |
133 | | HANDLE_SBR_PREV_FRAME_DATA h_prev_data); |
134 | | static void timeCompensateFirstEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData, |
135 | | HANDLE_SBR_FRAME_DATA h_sbr_data, |
136 | | HANDLE_SBR_PREV_FRAME_DATA h_prev_data); |
137 | | static int checkEnvelopeData(HANDLE_SBR_HEADER_DATA hHeaderData, |
138 | | HANDLE_SBR_FRAME_DATA h_sbr_data, |
139 | | HANDLE_SBR_PREV_FRAME_DATA h_prev_data); |
140 | | |
141 | 39.4k | #define SBR_ENERGY_PAN_OFFSET (12 << ENV_EXP_FRACT) |
142 | 125k | #define SBR_MAX_ENERGY (35 << ENV_EXP_FRACT) |
143 | | |
144 | 93.3k | #define DECAY (1 << ENV_EXP_FRACT) |
145 | | |
146 | | #if ENV_EXP_FRACT |
147 | | #define DECAY_COUPLING \ |
148 | | (1 << (ENV_EXP_FRACT - 1)) /*!< corresponds to a value of 0.5 */ |
149 | | #else |
150 | | #define DECAY_COUPLING \ |
151 | 19.7k | 1 /*!< If the energy data is not shifted, use 1 instead of 0.5 */ |
152 | | #endif |
153 | | |
154 | | /*! |
155 | | \brief Convert table index |
156 | | */ |
157 | | static int indexLow2High(int offset, /*!< mapping factor */ |
158 | | int index, /*!< index to scalefactor band */ |
159 | | int res) /*!< frequency resolution */ |
160 | 1.63M | { |
161 | 1.63M | if (res == 0) { |
162 | 75.2k | if (offset >= 0) { |
163 | 75.2k | if (index < offset) |
164 | 9.03k | return (index); |
165 | 66.2k | else |
166 | 66.2k | return (2 * index - offset); |
167 | 75.2k | } else { |
168 | 0 | offset = -offset; |
169 | 0 | if (index < offset) |
170 | 0 | return (2 * index + index); |
171 | 0 | else |
172 | 0 | return (2 * index + offset); |
173 | 0 | } |
174 | 75.2k | } else |
175 | 1.55M | return (index); |
176 | 1.63M | } |
177 | | |
178 | | /*! |
179 | | \brief Update previous envelope value for delta-coding |
180 | | |
181 | | The current envelope values needs to be stored for delta-coding |
182 | | in the next frame. The stored envelope is always represented with |
183 | | the high frequency resolution. If the current envelope uses the |
184 | | low frequency resolution, the energy value will be mapped to the |
185 | | corresponding high-res bands. |
186 | | */ |
187 | | static void mapLowResEnergyVal( |
188 | | FIXP_SGL currVal, /*!< current energy value */ |
189 | | FIXP_SGL *prevData, /*!< pointer to previous data vector */ |
190 | | int offset, /*!< mapping factor */ |
191 | | int index, /*!< index to scalefactor band */ |
192 | | int res) /*!< frequeny resolution */ |
193 | 2.76M | { |
194 | 2.76M | if (res == 0) { |
195 | 761k | if (offset >= 0) { |
196 | 761k | if (index < offset) |
197 | 49.9k | prevData[index] = currVal; |
198 | 711k | else { |
199 | 711k | prevData[2 * index - offset] = currVal; |
200 | 711k | prevData[2 * index + 1 - offset] = currVal; |
201 | 711k | } |
202 | 761k | } else { |
203 | 0 | offset = -offset; |
204 | 0 | if (index < offset) { |
205 | 0 | prevData[3 * index] = currVal; |
206 | 0 | prevData[3 * index + 1] = currVal; |
207 | 0 | prevData[3 * index + 2] = currVal; |
208 | 0 | } else { |
209 | 0 | prevData[2 * index + offset] = currVal; |
210 | 0 | prevData[2 * index + 1 + offset] = currVal; |
211 | 0 | } |
212 | 0 | } |
213 | 761k | } else |
214 | 2.00M | prevData[index] = currVal; |
215 | 2.76M | } |
216 | | |
217 | | /*! |
218 | | \brief Convert raw envelope and noisefloor data to energy levels |
219 | | |
220 | | This function is being called by sbrDecoder_ParseElement() and provides two |
221 | | important algorithms: |
222 | | |
223 | | First the function decodes envelopes and noise floor levels as described in |
224 | | requantizeEnvelopeData() and sbr_envelope_unmapping(). The function also |
225 | | implements concealment algorithms in case there are errors within the sbr |
226 | | data. For both operations fractional arithmetic is used. Therefore you might |
227 | | encounter different output values on your target system compared to the |
228 | | reference implementation. |
229 | | */ |
230 | | void decodeSbrData( |
231 | | HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ |
232 | | HANDLE_SBR_FRAME_DATA |
233 | | h_data_left, /*!< pointer to left channel frame data */ |
234 | | HANDLE_SBR_PREV_FRAME_DATA |
235 | | h_prev_data_left, /*!< pointer to left channel previous frame data */ |
236 | | HANDLE_SBR_FRAME_DATA |
237 | | h_data_right, /*!< pointer to right channel frame data */ |
238 | | HANDLE_SBR_PREV_FRAME_DATA |
239 | | h_prev_data_right) /*!< pointer to right channel previous frame data */ |
240 | 246k | { |
241 | 246k | FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS]; |
242 | 246k | int errLeft; |
243 | | |
244 | | /* Save previous energy values to be able to reuse them later for concealment. |
245 | | */ |
246 | 246k | FDKmemcpy(tempSfbNrgPrev, h_prev_data_left->sfb_nrg_prev, |
247 | 246k | MAX_FREQ_COEFFS * sizeof(FIXP_SGL)); |
248 | | |
249 | 246k | if (hHeaderData->frameErrorFlag || hHeaderData->bs_info.pvc_mode == 0) { |
250 | 123k | decodeEnvelope(hHeaderData, h_data_left, h_prev_data_left, |
251 | 123k | h_prev_data_right); |
252 | 123k | } else { |
253 | 122k | FDK_ASSERT(h_data_right == NULL); |
254 | 122k | } |
255 | 246k | decodeNoiseFloorlevels(hHeaderData, h_data_left, h_prev_data_left); |
256 | | |
257 | 246k | if (h_data_right != NULL) { |
258 | 82.4k | errLeft = hHeaderData->frameErrorFlag; |
259 | 82.4k | decodeEnvelope(hHeaderData, h_data_right, h_prev_data_right, |
260 | 82.4k | h_prev_data_left); |
261 | 82.4k | decodeNoiseFloorlevels(hHeaderData, h_data_right, h_prev_data_right); |
262 | | |
263 | 82.4k | if (!errLeft && hHeaderData->frameErrorFlag) { |
264 | | /* If an error occurs in the right channel where the left channel seemed |
265 | | ok, we apply concealment also on the left channel. This ensures that |
266 | | the coupling modes of both channels match and that we have the same |
267 | | number of envelopes in coupling mode. However, as the left channel has |
268 | | already been processed before, the resulting energy levels are not the |
269 | | same as if the left channel had been concealed during the first call of |
270 | | decodeEnvelope(). |
271 | | */ |
272 | | /* Restore previous energy values for concealment, because the values have |
273 | | been overwritten by the first call of decodeEnvelope(). */ |
274 | 6.79k | FDKmemcpy(h_prev_data_left->sfb_nrg_prev, tempSfbNrgPrev, |
275 | 6.79k | MAX_FREQ_COEFFS * sizeof(FIXP_SGL)); |
276 | | /* Do concealment */ |
277 | 6.79k | decodeEnvelope(hHeaderData, h_data_left, h_prev_data_left, |
278 | 6.79k | h_prev_data_right); |
279 | 6.79k | } |
280 | | |
281 | 82.4k | if (h_data_left->coupling) { |
282 | 33.1k | sbr_envelope_unmapping(hHeaderData, h_data_left, h_data_right); |
283 | 33.1k | } |
284 | 82.4k | } |
285 | | |
286 | | /* Display the data for debugging: */ |
287 | 246k | } |
288 | | |
289 | | /*! |
290 | | \brief Convert from coupled channels to independent L/R data |
291 | | */ |
292 | | static void sbr_envelope_unmapping( |
293 | | HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ |
294 | | HANDLE_SBR_FRAME_DATA h_data_left, /*!< pointer to left channel */ |
295 | | HANDLE_SBR_FRAME_DATA h_data_right) /*!< pointer to right channel */ |
296 | 33.1k | { |
297 | 33.1k | int i; |
298 | 33.1k | FIXP_SGL tempL_m, tempR_m, tempRplus1_m, newL_m, newR_m; |
299 | 33.1k | SCHAR tempL_e, tempR_e, tempRplus1_e, newL_e, newR_e; |
300 | | |
301 | | /* 1. Unmap (already dequantized) coupled envelope energies */ |
302 | | |
303 | 425k | for (i = 0; i < h_data_left->nScaleFactors; i++) { |
304 | 392k | tempR_m = (FIXP_SGL)((LONG)h_data_right->iEnvelope[i] & MASK_M); |
305 | 392k | tempR_e = (SCHAR)((LONG)h_data_right->iEnvelope[i] & MASK_E); |
306 | | |
307 | 392k | tempR_e -= (18 + NRG_EXP_OFFSET); /* -18 = ld(UNMAPPING_SCALE / |
308 | | h_data_right->nChannels) */ |
309 | 392k | tempL_m = (FIXP_SGL)((LONG)h_data_left->iEnvelope[i] & MASK_M); |
310 | 392k | tempL_e = (SCHAR)((LONG)h_data_left->iEnvelope[i] & MASK_E); |
311 | | |
312 | 392k | tempL_e -= NRG_EXP_OFFSET; |
313 | | |
314 | | /* Calculate tempRight+1 */ |
315 | 392k | FDK_add_MantExp(tempR_m, tempR_e, FL2FXCONST_SGL(0.5f), 1, /* 1.0 */ |
316 | 392k | &tempRplus1_m, &tempRplus1_e); |
317 | | |
318 | 392k | FDK_divide_MantExp(tempL_m, tempL_e + 1, /* 2 * tempLeft */ |
319 | 392k | tempRplus1_m, tempRplus1_e, &newR_m, &newR_e); |
320 | | |
321 | 392k | if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) { |
322 | 435 | newR_m >>= 1; |
323 | 435 | newR_e += 1; |
324 | 435 | } |
325 | | |
326 | 392k | newL_m = FX_DBL2FX_SGL(fMult(tempR_m, newR_m)); |
327 | 392k | newL_e = tempR_e + newR_e; |
328 | | |
329 | 392k | h_data_right->iEnvelope[i] = |
330 | 392k | ((FIXP_SGL)((SHORT)(FIXP_SGL)(newR_m + ROUNDING) & MASK_M)) + |
331 | 392k | (FIXP_SGL)((SHORT)(FIXP_SGL)(newR_e + NRG_EXP_OFFSET) & MASK_E); |
332 | 392k | h_data_left->iEnvelope[i] = |
333 | 392k | ((FIXP_SGL)((SHORT)(FIXP_SGL)(newL_m + ROUNDING) & MASK_M)) + |
334 | 392k | (FIXP_SGL)((SHORT)(FIXP_SGL)(newL_e + NRG_EXP_OFFSET) & MASK_E); |
335 | 392k | } |
336 | | |
337 | | /* 2. Dequantize and unmap coupled noise floor levels */ |
338 | | |
339 | 136k | for (i = 0; i < hHeaderData->freqBandData.nNfb * |
340 | 136k | h_data_left->frameInfo.nNoiseEnvelopes; |
341 | 103k | i++) { |
342 | 103k | tempL_e = (SCHAR)(6 - (LONG)h_data_left->sbrNoiseFloorLevel[i]); |
343 | 103k | tempR_e = (SCHAR)((LONG)h_data_right->sbrNoiseFloorLevel[i] - |
344 | 103k | 12) /*SBR_ENERGY_PAN_OFFSET*/; |
345 | | |
346 | | /* Calculate tempR+1 */ |
347 | 103k | FDK_add_MantExp(FL2FXCONST_SGL(0.5f), 1 + tempR_e, /* tempR */ |
348 | 103k | FL2FXCONST_SGL(0.5f), 1, /* 1.0 */ |
349 | 103k | &tempRplus1_m, &tempRplus1_e); |
350 | | |
351 | | /* Calculate 2*tempLeft/(tempR+1) */ |
352 | 103k | FDK_divide_MantExp(FL2FXCONST_SGL(0.5f), tempL_e + 2, /* 2 * tempLeft */ |
353 | 103k | tempRplus1_m, tempRplus1_e, &newR_m, &newR_e); |
354 | | |
355 | | /* if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) { |
356 | | newR_m >>= 1; |
357 | | newR_e += 1; |
358 | | } */ |
359 | | |
360 | | /* L = tempR * R */ |
361 | 103k | newL_m = newR_m; |
362 | 103k | newL_e = newR_e + tempR_e; |
363 | 103k | h_data_right->sbrNoiseFloorLevel[i] = |
364 | 103k | ((FIXP_SGL)((SHORT)(FIXP_SGL)(newR_m + ROUNDING) & MASK_M)) + |
365 | 103k | (FIXP_SGL)((SHORT)(FIXP_SGL)(newR_e + NOISE_EXP_OFFSET) & MASK_E); |
366 | 103k | h_data_left->sbrNoiseFloorLevel[i] = |
367 | 103k | ((FIXP_SGL)((SHORT)(FIXP_SGL)(newL_m + ROUNDING) & MASK_M)) + |
368 | 103k | (FIXP_SGL)((SHORT)(FIXP_SGL)(newL_e + NOISE_EXP_OFFSET) & MASK_E); |
369 | 103k | } |
370 | 33.1k | } |
371 | | |
372 | | /*! |
373 | | \brief Simple alternative to the real SBR concealment |
374 | | |
375 | | If the real frameInfo is not available due to a frame loss, a replacement will |
376 | | be constructed with 1 envelope spanning the whole frame (FIX-FIX). |
377 | | The delta-coded energies are set to negative values, resulting in a fade-down. |
378 | | In case of coupling, the balance-channel will move towards the center. |
379 | | */ |
380 | | static void leanSbrConcealment( |
381 | | HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ |
382 | | HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */ |
383 | | HANDLE_SBR_PREV_FRAME_DATA h_prev_data /*!< pointer to data of last frame */ |
384 | 113k | ) { |
385 | 113k | FIXP_SGL target; /* targeted level for sfb_nrg_prev during fade-down */ |
386 | 113k | FIXP_SGL step; /* speed of fade */ |
387 | 113k | int i; |
388 | | |
389 | 113k | int currentStartPos = |
390 | 113k | fMax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots); |
391 | 113k | int currentStopPos = hHeaderData->numberTimeSlots; |
392 | | |
393 | | /* Use some settings of the previous frame */ |
394 | 113k | h_sbr_data->ampResolutionCurrentFrame = h_prev_data->ampRes; |
395 | 113k | h_sbr_data->coupling = h_prev_data->coupling; |
396 | 678k | for (i = 0; i < MAX_INVF_BANDS; i++) |
397 | 565k | h_sbr_data->sbr_invf_mode[i] = h_prev_data->sbr_invf_mode[i]; |
398 | | |
399 | | /* Generate concealing control data */ |
400 | | |
401 | 113k | h_sbr_data->frameInfo.nEnvelopes = 1; |
402 | 113k | h_sbr_data->frameInfo.borders[0] = currentStartPos; |
403 | 113k | h_sbr_data->frameInfo.borders[1] = currentStopPos; |
404 | 113k | h_sbr_data->frameInfo.freqRes[0] = 1; |
405 | 113k | h_sbr_data->frameInfo.tranEnv = -1; /* no transient */ |
406 | 113k | h_sbr_data->frameInfo.nNoiseEnvelopes = 1; |
407 | 113k | h_sbr_data->frameInfo.bordersNoise[0] = currentStartPos; |
408 | 113k | h_sbr_data->frameInfo.bordersNoise[1] = currentStopPos; |
409 | | |
410 | 113k | h_sbr_data->nScaleFactors = hHeaderData->freqBandData.nSfb[1]; |
411 | | |
412 | | /* Generate fake envelope data */ |
413 | | |
414 | 113k | h_sbr_data->domain_vec[0] = 1; |
415 | | |
416 | 113k | if (h_sbr_data->coupling == COUPLING_BAL) { |
417 | 19.7k | target = (FIXP_SGL)SBR_ENERGY_PAN_OFFSET; |
418 | 19.7k | step = (FIXP_SGL)DECAY_COUPLING; |
419 | 93.3k | } else { |
420 | 93.3k | target = FL2FXCONST_SGL(0.0f); |
421 | 93.3k | step = (FIXP_SGL)DECAY; |
422 | 93.3k | } |
423 | 113k | if (hHeaderData->bs_info.ampResolution == 0) { |
424 | 57.2k | target <<= 1; |
425 | 57.2k | step <<= 1; |
426 | 57.2k | } |
427 | | |
428 | 1.36M | for (i = 0; i < h_sbr_data->nScaleFactors; i++) { |
429 | 1.25M | if (h_prev_data->sfb_nrg_prev[i] > target) |
430 | 642k | h_sbr_data->iEnvelope[i] = -step; |
431 | 610k | else |
432 | 610k | h_sbr_data->iEnvelope[i] = step; |
433 | 1.25M | } |
434 | | |
435 | | /* Noisefloor levels are always cleared ... */ |
436 | | |
437 | 113k | h_sbr_data->domain_vec_noise[0] = 1; |
438 | 113k | FDKmemclear(h_sbr_data->sbrNoiseFloorLevel, |
439 | 113k | sizeof(h_sbr_data->sbrNoiseFloorLevel)); |
440 | | |
441 | | /* ... and so are the sines */ |
442 | 113k | FDKmemclear(h_sbr_data->addHarmonics, |
443 | 113k | sizeof(ULONG) * ADD_HARMONICS_FLAGS_SIZE); |
444 | 113k | } |
445 | | |
446 | | /*! |
447 | | \brief Build reference energies and noise levels from bitstream elements |
448 | | */ |
449 | | static void decodeEnvelope( |
450 | | HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ |
451 | | HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */ |
452 | | HANDLE_SBR_PREV_FRAME_DATA |
453 | | h_prev_data, /*!< pointer to data of last frame */ |
454 | | HANDLE_SBR_PREV_FRAME_DATA |
455 | | otherChannel /*!< other channel's last frame data */ |
456 | 238k | ) { |
457 | 238k | int i; |
458 | 238k | int fFrameError = hHeaderData->frameErrorFlag; |
459 | 238k | FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS]; |
460 | | |
461 | 238k | if (!fFrameError) { |
462 | | /* |
463 | | To avoid distortions after bad frames, set the error flag if delta coding |
464 | | in time occurs. However, SBR can take a little longer to come up again. |
465 | | */ |
466 | 146k | if (h_prev_data->frameErrorFlag) { |
467 | 68.7k | if (h_sbr_data->domain_vec[0] != 0) { |
468 | 7.49k | fFrameError = 1; |
469 | 7.49k | } |
470 | 77.6k | } else { |
471 | | /* Check that the previous stop position and the current start position |
472 | | match. (Could be done in checkFrameInfo(), but the previous frame data |
473 | | is not available there) */ |
474 | 77.6k | if (h_sbr_data->frameInfo.borders[0] != |
475 | 77.6k | h_prev_data->stopPos - hHeaderData->numberTimeSlots) { |
476 | | /* Both the previous as well as the current frame are flagged to be ok, |
477 | | * but they do not match! */ |
478 | 13.2k | if (h_sbr_data->domain_vec[0] == 1) { |
479 | | /* Prefer concealment over delta-time coding between the mismatching |
480 | | * frames */ |
481 | 64 | fFrameError = 1; |
482 | 13.1k | } else { |
483 | | /* Close the gap in time by triggering timeCompensateFirstEnvelope() |
484 | | */ |
485 | 13.1k | fFrameError = 1; |
486 | 13.1k | } |
487 | 13.2k | } |
488 | 77.6k | } |
489 | 146k | } |
490 | | |
491 | 238k | if (fFrameError) /* Error is detected */ |
492 | 113k | { |
493 | 113k | leanSbrConcealment(hHeaderData, h_sbr_data, h_prev_data); |
494 | | |
495 | | /* decode the envelope data to linear PCM */ |
496 | 113k | deltaToLinearPcmEnvelopeDecoding(hHeaderData, h_sbr_data, h_prev_data); |
497 | 113k | } else /*Do a temporary dummy decoding and check that the envelope values are |
498 | | within limits */ |
499 | 125k | { |
500 | 125k | if (h_prev_data->frameErrorFlag) { |
501 | 61.2k | timeCompensateFirstEnvelope(hHeaderData, h_sbr_data, h_prev_data); |
502 | 61.2k | if (h_sbr_data->coupling != h_prev_data->coupling) { |
503 | | /* |
504 | | Coupling mode has changed during concealment. |
505 | | The stored energy levels need to be converted. |
506 | | */ |
507 | 157k | for (i = 0; i < hHeaderData->freqBandData.nSfb[1]; i++) { |
508 | | /* Former Level-Channel will be used for both channels */ |
509 | 148k | if (h_prev_data->coupling == COUPLING_BAL) { |
510 | 8.26k | h_prev_data->sfb_nrg_prev[i] = |
511 | 8.26k | (otherChannel != NULL) ? otherChannel->sfb_nrg_prev[i] |
512 | 8.26k | : (FIXP_SGL)SBR_ENERGY_PAN_OFFSET; |
513 | 8.26k | } |
514 | | /* Former L/R will be combined as the new Level-Channel */ |
515 | 139k | else if (h_sbr_data->coupling == COUPLING_LEVEL && |
516 | 139k | otherChannel != NULL) { |
517 | 17.8k | h_prev_data->sfb_nrg_prev[i] = (h_prev_data->sfb_nrg_prev[i] + |
518 | 17.8k | otherChannel->sfb_nrg_prev[i]) >> |
519 | 17.8k | 1; |
520 | 122k | } else if (h_sbr_data->coupling == COUPLING_BAL) { |
521 | 11.4k | h_prev_data->sfb_nrg_prev[i] = (FIXP_SGL)SBR_ENERGY_PAN_OFFSET; |
522 | 11.4k | } |
523 | 148k | } |
524 | 9.19k | } |
525 | 61.2k | } |
526 | 125k | FDKmemcpy(tempSfbNrgPrev, h_prev_data->sfb_nrg_prev, |
527 | 125k | MAX_FREQ_COEFFS * sizeof(FIXP_SGL)); |
528 | | |
529 | 125k | deltaToLinearPcmEnvelopeDecoding(hHeaderData, h_sbr_data, h_prev_data); |
530 | | |
531 | 125k | fFrameError = checkEnvelopeData(hHeaderData, h_sbr_data, h_prev_data); |
532 | | |
533 | 125k | if (fFrameError) { |
534 | 25.8k | hHeaderData->frameErrorFlag = 1; |
535 | 25.8k | FDKmemcpy(h_prev_data->sfb_nrg_prev, tempSfbNrgPrev, |
536 | 25.8k | MAX_FREQ_COEFFS * sizeof(FIXP_SGL)); |
537 | 25.8k | decodeEnvelope(hHeaderData, h_sbr_data, h_prev_data, otherChannel); |
538 | 25.8k | return; |
539 | 25.8k | } |
540 | 125k | } |
541 | | |
542 | 212k | requantizeEnvelopeData(h_sbr_data, h_sbr_data->ampResolutionCurrentFrame); |
543 | | |
544 | 212k | hHeaderData->frameErrorFlag = fFrameError; |
545 | 212k | } |
546 | | |
547 | | /*! |
548 | | \brief Verify that envelope energies are within the allowed range |
549 | | \return 0 if all is fine, 1 if an envelope value was too high |
550 | | */ |
551 | | static int checkEnvelopeData( |
552 | | HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ |
553 | | HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */ |
554 | | HANDLE_SBR_PREV_FRAME_DATA h_prev_data /*!< pointer to data of last frame */ |
555 | 125k | ) { |
556 | 125k | FIXP_SGL *iEnvelope = h_sbr_data->iEnvelope; |
557 | 125k | FIXP_SGL *sfb_nrg_prev = h_prev_data->sfb_nrg_prev; |
558 | 125k | int i = 0, errorFlag = 0; |
559 | 125k | FIXP_SGL sbr_max_energy = (h_sbr_data->ampResolutionCurrentFrame == 1) |
560 | 125k | ? SBR_MAX_ENERGY |
561 | 125k | : (SBR_MAX_ENERGY << 1); |
562 | | |
563 | | /* |
564 | | Range check for current energies |
565 | | */ |
566 | 1.63M | for (i = 0; i < h_sbr_data->nScaleFactors; i++) { |
567 | 1.51M | if (iEnvelope[i] > sbr_max_energy) { |
568 | 92.9k | errorFlag = 1; |
569 | 92.9k | } |
570 | 1.51M | if (iEnvelope[i] < FL2FXCONST_SGL(0.0f)) { |
571 | 86.5k | errorFlag = 1; |
572 | | /* iEnvelope[i] = FL2FXCONST_SGL(0.0f); */ |
573 | 86.5k | } |
574 | 1.51M | } |
575 | | |
576 | | /* |
577 | | Range check for previous energies |
578 | | */ |
579 | 1.62M | for (i = 0; i < hHeaderData->freqBandData.nSfb[1]; i++) { |
580 | 1.50M | sfb_nrg_prev[i] = fixMax(sfb_nrg_prev[i], FL2FXCONST_SGL(0.0f)); |
581 | 1.50M | sfb_nrg_prev[i] = fixMin(sfb_nrg_prev[i], sbr_max_energy); |
582 | 1.50M | } |
583 | | |
584 | 125k | return (errorFlag); |
585 | 125k | } |
586 | | |
587 | | /*! |
588 | | \brief Verify that the noise levels are within the allowed range |
589 | | |
590 | | The function is equivalent to checkEnvelopeData(). |
591 | | When the noise-levels are being decoded, it is already too late for |
592 | | concealment. Therefore the noise levels are simply limited here. |
593 | | */ |
594 | | static void limitNoiseLevels( |
595 | | HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ |
596 | | HANDLE_SBR_FRAME_DATA h_sbr_data) /*!< pointer to current data */ |
597 | 328k | { |
598 | 328k | int i; |
599 | 328k | int nNfb = hHeaderData->freqBandData.nNfb; |
600 | | |
601 | | /* |
602 | | Set range limits. The exact values depend on the coupling mode. |
603 | | However this limitation is primarily intended to avoid unlimited |
604 | | accumulation of the delta-coded noise levels. |
605 | | */ |
606 | 328k | #define lowerLimit \ |
607 | 328k | ((FIXP_SGL)0) /* lowerLimit actually refers to the _highest_ noise energy */ |
608 | 328k | #define upperLimit \ |
609 | 328k | ((FIXP_SGL)35) /* upperLimit actually refers to the _lowest_ noise energy */ |
610 | | |
611 | | /* |
612 | | Range check for current noise levels |
613 | | */ |
614 | 1.44M | for (i = 0; i < h_sbr_data->frameInfo.nNoiseEnvelopes * nNfb; i++) { |
615 | 1.11M | h_sbr_data->sbrNoiseFloorLevel[i] = |
616 | 1.11M | fixMin(h_sbr_data->sbrNoiseFloorLevel[i], upperLimit); |
617 | 1.11M | h_sbr_data->sbrNoiseFloorLevel[i] = |
618 | 1.11M | fixMax(h_sbr_data->sbrNoiseFloorLevel[i], lowerLimit); |
619 | 1.11M | } |
620 | 328k | } |
621 | | |
622 | | /*! |
623 | | \brief Compensate for the wrong timing that might occur after a frame error. |
624 | | */ |
625 | | static void timeCompensateFirstEnvelope( |
626 | | HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ |
627 | | HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to actual data */ |
628 | | HANDLE_SBR_PREV_FRAME_DATA |
629 | | h_prev_data) /*!< pointer to data of last frame */ |
630 | 61.2k | { |
631 | 61.2k | int i, nScalefactors; |
632 | 61.2k | FRAME_INFO *pFrameInfo = &h_sbr_data->frameInfo; |
633 | 61.2k | UCHAR *nSfb = hHeaderData->freqBandData.nSfb; |
634 | 61.2k | int estimatedStartPos = |
635 | 61.2k | fMax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots); |
636 | 61.2k | int refLen, newLen, shift; |
637 | 61.2k | FIXP_SGL deltaExp; |
638 | | |
639 | | /* Original length of first envelope according to bitstream */ |
640 | 61.2k | refLen = pFrameInfo->borders[1] - pFrameInfo->borders[0]; |
641 | | /* Corrected length of first envelope (concealing can make the first envelope |
642 | | * longer) */ |
643 | 61.2k | newLen = pFrameInfo->borders[1] - estimatedStartPos; |
644 | | |
645 | 61.2k | if (newLen <= 0) { |
646 | | /* An envelope length of <= 0 would not work, so we don't use it. |
647 | | May occur if the previous frame was flagged bad due to a mismatch |
648 | | of the old and new frame infos. */ |
649 | 23 | newLen = refLen; |
650 | 23 | estimatedStartPos = pFrameInfo->borders[0]; |
651 | 23 | } |
652 | | |
653 | 61.2k | deltaExp = FDK_getNumOctavesDiv8(newLen, refLen); |
654 | | |
655 | | /* Shift by -3 to rescale ld-table, ampRes-1 to enable coarser steps */ |
656 | 61.2k | shift = (FRACT_BITS - 1 - ENV_EXP_FRACT - 1 + |
657 | 61.2k | h_sbr_data->ampResolutionCurrentFrame - 3); |
658 | 61.2k | deltaExp = deltaExp >> shift; |
659 | 61.2k | pFrameInfo->borders[0] = estimatedStartPos; |
660 | 61.2k | pFrameInfo->bordersNoise[0] = estimatedStartPos; |
661 | | |
662 | 61.2k | if (h_sbr_data->coupling != COUPLING_BAL) { |
663 | 49.0k | nScalefactors = (pFrameInfo->freqRes[0]) ? nSfb[1] : nSfb[0]; |
664 | | |
665 | 425k | for (i = 0; i < nScalefactors; i++) |
666 | 376k | h_sbr_data->iEnvelope[i] = h_sbr_data->iEnvelope[i] + deltaExp; |
667 | 49.0k | } |
668 | 61.2k | } |
669 | | |
670 | | /*! |
671 | | \brief Convert each envelope value from logarithmic to linear domain |
672 | | |
673 | | Energy levels are transmitted in powers of 2, i.e. only the exponent |
674 | | is extracted from the bitstream. |
675 | | Therefore, normally only integer exponents can occur. However during |
676 | | fading (in case of a corrupt bitstream), a fractional part can also |
677 | | occur. The data in the array iEnvelope is shifted left by ENV_EXP_FRACT |
678 | | compared to an integer representation so that numbers smaller than 1 |
679 | | can be represented. |
680 | | |
681 | | This function calculates a mantissa corresponding to the fractional |
682 | | part of the exponent for each reference energy. The array iEnvelope |
683 | | is converted in place to save memory. Input and output data must |
684 | | be interpreted differently, as shown in the below figure: |
685 | | |
686 | | \image html EnvelopeData.png |
687 | | |
688 | | The data is then used in calculateSbrEnvelope(). |
689 | | */ |
690 | | static void requantizeEnvelopeData(HANDLE_SBR_FRAME_DATA h_sbr_data, |
691 | 212k | int ampResolution) { |
692 | 212k | int i; |
693 | 212k | FIXP_SGL mantissa; |
694 | 212k | int ampShift = 1 - ampResolution; |
695 | 212k | int exponent; |
696 | | |
697 | | /* In case that ENV_EXP_FRACT is changed to something else but 0 or 8, |
698 | | the initialization of this array has to be adapted! |
699 | | */ |
700 | | #if ENV_EXP_FRACT |
701 | | static const FIXP_SGL pow2[ENV_EXP_FRACT] = { |
702 | | FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 1))), /* 0.7071 */ |
703 | | FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 2))), /* 0.5946 */ |
704 | | FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 3))), |
705 | | FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 4))), |
706 | | FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 5))), |
707 | | FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 6))), |
708 | | FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 7))), |
709 | | FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 8))) /* 0.5013 */ |
710 | | }; |
711 | | |
712 | | int bit, mask; |
713 | | #endif |
714 | | |
715 | 2.60M | for (i = 0; i < h_sbr_data->nScaleFactors; i++) { |
716 | 2.39M | exponent = (LONG)h_sbr_data->iEnvelope[i]; |
717 | | |
718 | | #if ENV_EXP_FRACT |
719 | | |
720 | | exponent = exponent >> ampShift; |
721 | | mantissa = 0.5f; |
722 | | |
723 | | /* Amplify mantissa according to the fractional part of the |
724 | | exponent (result will be between 0.500000 and 0.999999) |
725 | | */ |
726 | | mask = 1; /* begin with lowest bit of exponent */ |
727 | | |
728 | | for (bit = ENV_EXP_FRACT - 1; bit >= 0; bit--) { |
729 | | if (exponent & mask) { |
730 | | /* The current bit of the exponent is set, |
731 | | multiply mantissa with the corresponding factor: */ |
732 | | mantissa = (FIXP_SGL)((mantissa * pow2[bit]) << 1); |
733 | | } |
734 | | /* Advance to next bit */ |
735 | | mask = mask << 1; |
736 | | } |
737 | | |
738 | | /* Make integer part of exponent right aligned */ |
739 | | exponent = exponent >> ENV_EXP_FRACT; |
740 | | |
741 | | #else |
742 | | /* In case of the high amplitude resolution, 1 bit of the exponent gets lost |
743 | | by the shift. This will be compensated by a mantissa of 0.5*sqrt(2) |
744 | | instead of 0.5 if that bit is 1. */ |
745 | 2.39M | mantissa = (exponent & ampShift) ? FL2FXCONST_SGL(0.707106781186548f) |
746 | 2.39M | : FL2FXCONST_SGL(0.5f); |
747 | 2.39M | exponent = exponent >> ampShift; |
748 | 2.39M | #endif |
749 | | |
750 | | /* |
751 | | Mantissa was set to 0.5 (instead of 1.0, therefore increase exponent by |
752 | | 1). Multiply by L=nChannels=64 by increasing exponent by another 6. |
753 | | => Increase exponent by 7 |
754 | | */ |
755 | 2.39M | exponent += 7 + NRG_EXP_OFFSET; |
756 | | |
757 | | /* Combine mantissa and exponent and write back the result */ |
758 | 2.39M | h_sbr_data->iEnvelope[i] = |
759 | 2.39M | ((FIXP_SGL)((SHORT)(FIXP_SGL)mantissa & MASK_M)) + |
760 | 2.39M | (FIXP_SGL)((SHORT)(FIXP_SGL)exponent & MASK_E); |
761 | 2.39M | } |
762 | 212k | } |
763 | | |
764 | | /*! |
765 | | \brief Build new reference energies from old ones and delta coded data |
766 | | */ |
767 | | static void deltaToLinearPcmEnvelopeDecoding( |
768 | | HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ |
769 | | HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */ |
770 | | HANDLE_SBR_PREV_FRAME_DATA h_prev_data) /*!< pointer to previous data */ |
771 | 238k | { |
772 | 238k | int i, domain, no_of_bands, band, freqRes; |
773 | | |
774 | 238k | FIXP_SGL *sfb_nrg_prev = h_prev_data->sfb_nrg_prev; |
775 | 238k | FIXP_SGL *ptr_nrg = h_sbr_data->iEnvelope; |
776 | | |
777 | 238k | int offset = |
778 | 238k | 2 * hHeaderData->freqBandData.nSfb[0] - hHeaderData->freqBandData.nSfb[1]; |
779 | | |
780 | 547k | for (i = 0; i < h_sbr_data->frameInfo.nEnvelopes; i++) { |
781 | 308k | domain = h_sbr_data->domain_vec[i]; |
782 | 308k | freqRes = h_sbr_data->frameInfo.freqRes[i]; |
783 | | |
784 | 308k | FDK_ASSERT(freqRes >= 0 && freqRes <= 1); |
785 | | |
786 | 308k | no_of_bands = hHeaderData->freqBandData.nSfb[freqRes]; |
787 | | |
788 | 308k | FDK_ASSERT(no_of_bands < (64)); |
789 | | |
790 | 308k | if (domain == 0) { |
791 | 158k | mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, 0, freqRes); |
792 | 158k | ptr_nrg++; |
793 | 1.13M | for (band = 1; band < no_of_bands; band++) { |
794 | 978k | *ptr_nrg = *ptr_nrg + *(ptr_nrg - 1); |
795 | 978k | mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, band, freqRes); |
796 | 978k | ptr_nrg++; |
797 | 978k | } |
798 | 158k | } else { |
799 | 1.78M | for (band = 0; band < no_of_bands; band++) { |
800 | 1.63M | *ptr_nrg = |
801 | 1.63M | *ptr_nrg + sfb_nrg_prev[indexLow2High(offset, band, freqRes)]; |
802 | 1.63M | mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, band, freqRes); |
803 | 1.63M | ptr_nrg++; |
804 | 1.63M | } |
805 | 150k | } |
806 | 308k | } |
807 | 238k | } |
808 | | |
809 | | /*! |
810 | | \brief Build new noise levels from old ones and delta coded data |
811 | | */ |
812 | | static void decodeNoiseFloorlevels( |
813 | | HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ |
814 | | HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */ |
815 | | HANDLE_SBR_PREV_FRAME_DATA h_prev_data) /*!< pointer to previous data */ |
816 | 328k | { |
817 | 328k | int i; |
818 | 328k | int nNfb = hHeaderData->freqBandData.nNfb; |
819 | 328k | int nNoiseFloorEnvelopes = h_sbr_data->frameInfo.nNoiseEnvelopes; |
820 | | |
821 | | /* Decode first noise envelope */ |
822 | | |
823 | 328k | if (h_sbr_data->domain_vec_noise[0] == 0) { |
824 | 217k | FIXP_SGL noiseLevel = h_sbr_data->sbrNoiseFloorLevel[0]; |
825 | 534k | for (i = 1; i < nNfb; i++) { |
826 | 317k | noiseLevel += h_sbr_data->sbrNoiseFloorLevel[i]; |
827 | 317k | h_sbr_data->sbrNoiseFloorLevel[i] = noiseLevel; |
828 | 317k | } |
829 | 217k | } else { |
830 | 339k | for (i = 0; i < nNfb; i++) { |
831 | 228k | h_sbr_data->sbrNoiseFloorLevel[i] += h_prev_data->prevNoiseLevel[i]; |
832 | 228k | } |
833 | 111k | } |
834 | | |
835 | | /* If present, decode the second noise envelope |
836 | | Note: nNoiseFloorEnvelopes can only be 1 or 2 */ |
837 | | |
838 | 328k | if (nNoiseFloorEnvelopes > 1) { |
839 | 148k | if (h_sbr_data->domain_vec_noise[1] == 0) { |
840 | 42.7k | FIXP_SGL noiseLevel = h_sbr_data->sbrNoiseFloorLevel[nNfb]; |
841 | 139k | for (i = nNfb + 1; i < 2 * nNfb; i++) { |
842 | 96.2k | noiseLevel += h_sbr_data->sbrNoiseFloorLevel[i]; |
843 | 96.2k | h_sbr_data->sbrNoiseFloorLevel[i] = noiseLevel; |
844 | 96.2k | } |
845 | 105k | } else { |
846 | 318k | for (i = 0; i < nNfb; i++) { |
847 | 212k | h_sbr_data->sbrNoiseFloorLevel[i + nNfb] += |
848 | 212k | h_sbr_data->sbrNoiseFloorLevel[i]; |
849 | 212k | } |
850 | 105k | } |
851 | 148k | } |
852 | | |
853 | 328k | limitNoiseLevels(hHeaderData, h_sbr_data); |
854 | | |
855 | | /* Update prevNoiseLevel with the last noise envelope */ |
856 | 1.09M | for (i = 0; i < nNfb; i++) |
857 | 763k | h_prev_data->prevNoiseLevel[i] = |
858 | 763k | h_sbr_data->sbrNoiseFloorLevel[i + nNfb * (nNoiseFloorEnvelopes - 1)]; |
859 | | |
860 | | /* Requantize the noise floor levels in COUPLING_OFF-mode */ |
861 | 328k | if (!h_sbr_data->coupling) { |
862 | 261k | int nf_e; |
863 | | |
864 | 1.16M | for (i = 0; i < nNoiseFloorEnvelopes * nNfb; i++) { |
865 | 903k | nf_e = 6 - (LONG)h_sbr_data->sbrNoiseFloorLevel[i] + 1 + NOISE_EXP_OFFSET; |
866 | | /* +1 to compensate for a mantissa of 0.5 instead of 1.0 */ |
867 | | |
868 | 903k | h_sbr_data->sbrNoiseFloorLevel[i] = |
869 | 903k | (FIXP_SGL)(((LONG)FL2FXCONST_SGL(0.5f)) + /* mantissa */ |
870 | 903k | (nf_e & MASK_E)); /* exponent */ |
871 | 903k | } |
872 | 261k | } |
873 | 328k | } |